diff --git a/.travis.yml b/.travis.yml index 7a40d37..b4e8c3d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,8 +18,5 @@ matrix: before_install: - make -f _dev/Makefile fmtcheck -install: - - sudo pip install docker - script: - - make -f _dev/Makefile build-all && make -f _dev/Makefile "$TEST_SUITE" + - go test -v -r=. diff --git a/_dev/.gitignore b/_dev/.gitignore deleted file mode 100644 index 23c0b93..0000000 --- a/_dev/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -/GOROOT -/go -/tris-localserver/tris-localserver -/tris-testclient/tris-testclient -/caddy/caddy -/caddy/echo diff --git a/_dev/Makefile b/_dev/Makefile deleted file mode 100644 index f5e0a84..0000000 --- a/_dev/Makefile +++ /dev/null @@ -1,140 +0,0 @@ -# Constants -MK_FILE_PATH = $(lastword $(MAKEFILE_LIST)) -PRJ_DIR = $(abspath $(dir $(MK_FILE_PATH))/..) -DEV_DIR = $(PRJ_DIR)/_dev -# Results will be produced in this directory (can be provided by a caller) -BUILD_DIR ?= $(PRJ_DIR)/_dev/GOROOT - -# Compiler -GO ?= go -DOCKER ?= docker -GIT ?= git - -# Build environment -OS ?= $(shell $(GO) env GOHOSTOS) -ARCH ?= $(shell $(GO) env GOHOSTARCH) -OS_ARCH := $(OS)_$(ARCH) -VER_OS_ARCH := $(shell $(GO) version | cut -d' ' -f 3)_$(OS)_$(ARCH) -GOROOT_ENV ?= $(shell $(GO) env GOROOT) -GOROOT_LOCAL = $(BUILD_DIR)/$(OS_ARCH) -# Flag indicates wheter invoke "go install -race std". Supported only on amd64 with CGO enabled -INSTALL_RACE:= $(words $(filter $(ARCH)_$(shell go env CGO_ENABLED), amd64_1)) -TMP_DIR := $(shell mktemp -d) - -# Test targets used for compatibility testing -TARGET_TEST_COMPAT=boring picotls tstclnt - -# Some target-specific constants -BORINGSSL_REVISION=ff433815b51c34496bb6bea13e73e29e5c278238 -BOGO_DOCKER_TRIS_LOCATION=/go/src/github.com/cloudflare/tls-tris - -# SIDH repository -SIDH_REPO ?= https://github.com/cloudflare/sidh.git -SIDH_REPO_TAG ?= Release_1.0 -# NOBS repo (SIKE depends on SHA3) -NOBS_REPO ?= https://github.com/henrydcase/nobscrypto.git -NOBS_REPO_TAG ?= Release_0.1 - -############### -# -# Build targets -# -############################## -$(BUILD_DIR)/$(OS_ARCH)/.ok_$(VER_OS_ARCH): clean - -# Create clean directory structure - mkdir -p "$(GOROOT_LOCAL)/pkg" - -# Copy src/tools from system GOROOT - cp -Hr $(GOROOT_ENV)/src $(GOROOT_LOCAL)/src - cp -Hr $(GOROOT_ENV)/pkg/include $(GOROOT_LOCAL)/pkg/include - cp -Hr $(GOROOT_ENV)/pkg/tool $(GOROOT_LOCAL)/pkg/tool - -# Swap TLS implementation - rm -r $(GOROOT_LOCAL)/src/crypto/tls/* - rsync -rltgoD $(PRJ_DIR)/ $(GOROOT_LOCAL)/src/crypto/tls/ --exclude=$(lastword $(subst /, ,$(DEV_DIR))) - -# Apply additional patches - for p in $(wildcard $(DEV_DIR)/patches/*); do patch -d "$(GOROOT_LOCAL)" -p1 < "$$p"; done - -# Vendor NOBS library - $(GIT) clone $(NOBS_REPO) $(TMP_DIR)/nobs - cd $(TMP_DIR)/nobs; $(GIT) checkout tags/$(NOBS_REPO_TAG) - cd $(TMP_DIR)/nobs; make vendor-sidh-for-tls - cp -rf $(TMP_DIR)/nobs/tls_vendor/* $(GOROOT_LOCAL)/src/vendor/ - -# Vendor SIDH library - $(GIT) clone $(SIDH_REPO) $(TMP_DIR)/sidh - cd $(TMP_DIR)/sidh; $(GIT) checkout tags/$(SIDH_REPO_TAG) - cd $(TMP_DIR)/sidh; make vendor - cp -rf $(TMP_DIR)/sidh/build/vendor/* $(GOROOT_LOCAL)/src/vendor/ - -# Create go package - GOARCH=$(ARCH) GOROOT="$(GOROOT_LOCAL)" $(GO) install -v std -ifeq ($(INSTALL_RACE),1) - GOARCH=$(ARCH) GOROOT="$(GOROOT_LOCAL)" $(GO) install -race -v std -endif - rm -rf $(TMP_DIR) - @touch "$@" - -build-test-%: $(BUILD_DIR)/$(OS_ARCH)/.ok_$(VER_OS_ARCH) - $(DOCKER) build $(BUILDARG) -t tls-tris:$* $(DEV_DIR)/$* - $(DOCKER) build $(BUILDARG) -t $(*)-localserver $(DEV_DIR)/$* - -build-all: \ - build-test-tris-client \ - build-test-tris-server \ - build-test-bogo \ - $(addprefix build-test-,$(TARGET_TEST_COMPAT)) - -# Builds TRIS client -build-test-tris-client: $(BUILD_DIR)/$(OS_ARCH)/.ok_$(VER_OS_ARCH) - cd $(DEV_DIR)/tris-testclient; CGO_ENABLED=0 GOROOT="$(GOROOT_LOCAL)" $(GO) build -v -i . - $(DOCKER) build -t tris-testclient $(DEV_DIR)/tris-testclient - -# Builds TRIS server -build-test-tris-server: $(BUILD_DIR)/$(OS_ARCH)/.ok_$(VER_OS_ARCH) - cd $(DEV_DIR)/tris-localserver; CGO_ENABLED=0 GOROOT="$(GOROOT_LOCAL)" $(GO) build -v -i . - $(DOCKER) build -t tris-localserver $(DEV_DIR)/tris-localserver - -# BoringSSL specific stuff -build-test-boring: BUILDARG=--build-arg REVISION=$(BORINGSSL_REVISION) - -# TODO: This probably doesn't work -build-caddy: $(BUILD_DIR)/$(OS_ARCH)/.ok_$(VER_OS_ARCH) - CGO_ENABLED=0 GOROOT="$(GOROOT_LOCAL)" $(GO) build github.com/mholt/caddy - -############### -# -# Test targets -# -############################## -test: \ - test-unit \ - test-bogo \ - test-interop - -test-unit: $(BUILD_DIR)/$(OS_ARCH)/.ok_$(VER_OS_ARCH) - GOROOT="$(GOROOT_LOCAL)" $(GO) test -race crypto/tls - -test-bogo: - $(DOCKER) run --rm -v $(PRJ_DIR):$(BOGO_DOCKER_TRIS_LOCATION) tls-tris:bogo - -test-interop: - $(DEV_DIR)/interop_test_runner -v - -############### -# -# Utils -# -############################## -clean: - rm -rf $(BUILD_DIR)/$(OS_ARCH) - -clean-all: clean - rm -rf $(BUILD_DIR) - -fmtcheck: - $(DEV_DIR)/utils/fmtcheck.sh - -.PHONY: $(BUILD_DIR) clean build build-test test test-unit test-bogo test-interop diff --git a/_dev/bogo/Dockerfile b/_dev/bogo/Dockerfile deleted file mode 100644 index 2bf4233..0000000 --- a/_dev/bogo/Dockerfile +++ /dev/null @@ -1,38 +0,0 @@ -FROM golang:1.11-alpine - -RUN apk add --update \ - git \ - make \ - bash \ - patch \ - rsync \ - && rm -rf /var/cache/apk/* - -ENV CGO_ENABLED=0 - -RUN git clone https://github.com/henrydcase/crypto-tls-bogo-shim \ - /go/src/github.com/henrydcase/crypto-tls-bogo-shim - -# Draft 18 with client-tests branch -#ARG REVISION=3f5e87d6a1931b6f6930e4eadb7b2d0b2aa7c588 - -# Draft 22 with draft22 branch -#ARG REVISION=81cc32b846c9fe2ea32613287e57a6a0db7bbb9a - -# Draft 22 with draft22-client branch (client-tests + draft22) -# ARG REVISION=f9729b5e4eafb1f1d313949388c3c2b167e84734 - -# Draft 23 -#ARG REVISION=d07b9e80a87c871c2569ce4aabd06695336c5dc5 - -# Draft 23 (+ client authentication) -# ARG REVISION=cd33ad248ae9490854f0077ca046b47cac3735bf - -# Draft 28 -ARG REVISION=33204d1eaa497819c6325998d7ba6b66316790f3 - -RUN cd /go/src/github.com/henrydcase/crypto-tls-bogo-shim && \ - git checkout $REVISION - -WORKDIR /go/src/github.com/henrydcase/crypto-tls-bogo-shim -CMD ["make", "run"] diff --git a/_dev/boring/Dockerfile b/_dev/boring/Dockerfile deleted file mode 100644 index 6e310f8..0000000 --- a/_dev/boring/Dockerfile +++ /dev/null @@ -1,69 +0,0 @@ -FROM alpine - -RUN apk add --update \ - git \ - cmake \ - patch \ - perl \ - python \ - build-base \ - go \ - ninja \ - && rm -rf /var/cache/apk/* - -RUN git clone https://boringssl.googlesource.com/boringssl - -RUN mkdir boringssl/build - -# Draft 14 -# ARG REVISION=88536c3 - -# Draft 15 -# RUN cd boringssl && git fetch https://boringssl.googlesource.com/boringssl refs/changes/40/10840/18:draft15 -# ARG REVISION=cae930d - -# Draft "14.25" (sigalg renumbering) -# ARG REVISION=af56fbd - -# Draft "14.25" w/ x25519 only -# ARG REVISION=c8b6b4f - -# Draft "14.5" (sigalg, x25519, version ext) -# ARG REVISION=54afdab - -# Draft 16 -# ARG REVISION=89917a5 - -# Draft 18 -# ARG REVISION=9b885c5 -# Draft 18, but with "bssl server -loop -www" support and build fix -# ARG REVISION=40b24c8154 - -# Draft 21 -# ARG REVISION=cd8470f - -# Draft 22 -# ARG REVISION=1530ef3e - -# Draft 23 -# ARG REVISION=cb15cfda29c0c60d8d74145b17c93b43a7667837 - -# Draft 28 -# ARG REVISION=861f384d7bc59241a9df1634ae938d8e75be2d30 - -# TLS 1.3 -ARG REVISION=ff433815b51c34496bb6bea13e73e29e5c278238 - -ADD sidh_$REVISION.patch / - -RUN cd boringssl && git fetch -RUN cd boringssl && git checkout $REVISION -RUN cd boringssl && patch -p1 < /sidh_$REVISION.patch -RUN cd boringssl/build && cmake -GNinja .. -RUN cd boringssl && ninja -C build - -ADD httpreq.txt /httpreq.txt -ADD run.sh /run.sh -ADD server.sh rsa.pem ecdsa.pem / -ADD client_rsa.key client_rsa.crt client_ca.crt / -ENTRYPOINT ["/run.sh"] diff --git a/_dev/boring/client_ca.crt b/_dev/boring/client_ca.crt deleted file mode 100644 index ad759dd..0000000 --- a/_dev/boring/client_ca.crt +++ /dev/null @@ -1,34 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIF6zCCA9OgAwIBAgIUC4U4HlbkVMrKKTFK0mNrMFDpRskwDQYJKoZIhvcNAQEL -BQAwfTELMAkGA1UEBhMCRlIxDTALBgNVBAgMBFBBQ0ExFzAVBgNVBAcMDkNhZ25l -cyBzdXIgTWVyMSIwIAYDVQQLDBlDZXJ0IFRlc3RpbmcgT3JnYW5pemF0aW9uMSIw -IAYDVQQDDBlDZXJ0IFRlc3RpbmcgT3JnYW5pemF0aW9uMB4XDTE5MDIyMjAwNDIz -OVoXDTQ2MDcwOTAwNDIzOVowfTELMAkGA1UEBhMCRlIxDTALBgNVBAgMBFBBQ0Ex -FzAVBgNVBAcMDkNhZ25lcyBzdXIgTWVyMSIwIAYDVQQLDBlDZXJ0IFRlc3Rpbmcg -T3JnYW5pemF0aW9uMSIwIAYDVQQDDBlDZXJ0IFRlc3RpbmcgT3JnYW5pemF0aW9u -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0z+DMLb7YIMFFNZpn+ve -NdT7GL9DPyV9ZWSHpUuDyme6Og6Mp5IpCLlKjNXtizX5aQ9xQ746slt70fivSV/r -tiEtayZkcwS7zHtc5f+U/S0hR1q5Zh3DaLQH9diSeuNFQN5pg7zQT5csJFlxf6EB -j/ioSBC+J1E8A2FAh0qDq+TvPPyZEEjcJy0oBuNHUnkC3rwjt24DAUI26rN/Qk9P -a6KR9bBOdHFFul3DEP/uPqWV9TvV5tJhP3J2RbfS79WljFy/lFIwvJvfQHYEjMt4 -/gq8yTSUgJ8zmgJQ1sgOKH1FzJd4EdAMquSYbElkc35jX8gggUNOUcwsIfJBnu41 -SC51JQruNT256zse76o8Dx3lSHiz5c6luZyJnZWWt6xWtfGEGMnckpn6cVvcbbgq -eWqmttgE2QTpgYoYUVcX/XFtsmZVTu05r8MZoqje5rgW9nEvvW+3M+eT5h0M9eGQ -bIT3D3tdXB2XWCjUWqxpZscFwyumGu7vdykBKLhMVR3nEpFfORnH+534vwi49fjz -WnN6fXAZZLPnGtEdWXNgs9JtgI5UheAQbcA3FT+M3maa88V2JrETLps405NYp6hJ -6msbS/AmV/eSilRmbGVj9TfKHb/BVHNYwVQ0Bu/QN2YQNQ9olOpIxXgKr6Y4tKZt -wTOMiCxZrnDQneQOTnW0NAMCAwEAAaNjMGEwHQYDVR0OBBYEFNLiS6YezH2bWiZ3 -TNbkQzMoBBB2MB8GA1UdIwQYMBaAFNLiS6YezH2bWiZ3TNbkQzMoBBB2MA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQAQ -cWIFOusSLKizqcqMsbMIY/Jzy0Tq5jzeOAQEQBztu7eJb208SG2EJtD6ylBQCF8t -FCxUbvWNrly1MJoMSXdn3uMz3kLKNQa6RENckwA1UuYZpdhvTUtmPun9QqFPJdqm -oi0paOVut9q3dplDy6MUknGN4tNWp2ZDfyvom3mUMfYGEO/FCWTy8eFd6cHRE9bw -tHkcX5r7GpDHH5vKXOF/deMp1Xgep5ZTasL13YwPiYgctst91pEfdcztjHW0mQNT -ZH/TUQDgs2UCjcvyeOlgoZixWOpkf1Qyje15k9qMb89/5hdarxvAQbG2BezQtzyk -bbCu1MQa2DBdAKbhQxas/DPSvSkA/y8v+hiovTWtPKErPnQqZqVy59KUTBWj8ZAj -5dkDVjBvUcsJ/6zHv0X9puEnIDZ8pK+Xn9LbcbPE7Nf1ikDyOqHmLmhGfWlEGvoD -3Q8f8zUySZ40mfqtVhc7OYqA66Q9quNQ4VBESVNiEJ/LuWHRXe74KqFdggsQqtS6 -UQQgw5lFnKHZ9pk2VlKzgpkmd5fLMOhcHWQbsah9TFOuW5vEhWGHNhGCyGouWTzD -mkwlPS8arj/ymUn6t/oiwSOA6GbjQLnTXvoAjdBxnukQlNY6TUDk+lSQw0qfZGIA -xZywUgRbLZH8TFUnuEQps35XnWrY8rrXVj9+9h0B4g== ------END CERTIFICATE----- diff --git a/_dev/boring/client_rsa.crt b/_dev/boring/client_rsa.crt deleted file mode 100644 index 8cc027c..0000000 --- a/_dev/boring/client_rsa.crt +++ /dev/null @@ -1,31 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFSjCCAzKgAwIBAgIUCKk2npLYEX2Z3Ceu1CwSKK50j04wDQYJKoZIhvcNAQEL -BQAwfTELMAkGA1UEBhMCRlIxDTALBgNVBAgMBFBBQ0ExFzAVBgNVBAcMDkNhZ25l -cyBzdXIgTWVyMSIwIAYDVQQLDBlDZXJ0IFRlc3RpbmcgT3JnYW5pemF0aW9uMSIw -IAYDVQQDDBlDZXJ0IFRlc3RpbmcgT3JnYW5pemF0aW9uMB4XDTE5MDIyMjAwNDMz -MloXDTQ2MDcwOTAwNDMzMlowfTELMAkGA1UEBhMCRlIxDTALBgNVBAgMBFBBQ0Ex -FzAVBgNVBAcMDkNhZ25lcyBzdXIgTWVyMSIwIAYDVQQLDBlDZXJ0IFRlc3Rpbmcg -T3JnYW5pemF0aW9uMSIwIAYDVQQDDBlDZXJ0IFRlc3RpbmcgT3JnYW5pemF0aW9u -MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEA0DQrWlCfijylutz28aTB -T9WDnvBWpJ535t/Clt4o2nv3Cp6JxvUVzYkdKuaLR295gyEBx9JSHiZxPiJoPVfp -wigmG0R9HvByAG5rhaQbQt99npoBaHMps1i12VxxFy1yaqZW6mrwrHMfV716rZ2M -AzWx7UfhutloBYeeluiziDWUSEuGeJG7kHdvUtGYlbRd/ElFWHOfAQ7Oc8UUjEHW -sorkqciqyAERV/H9hr5Rap/J/ERcFC8bNecS4t1Yh98WgIun/MbcBKQzo1LsWmOQ -dmaMBoG8g1mYRbNap8G/+aQbjfRi1zN0yaW1wtlLoBJmNgLjwYgaS/5Uey5NZMdb -NwIBA6OBwzCBwDAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAxBglghkgB -hvhCAQ0EJBYiQ2VydCBUZXN0aW5nIEludGVybWVkaWF0ZSAtIENsaWVudDAdBgNV -HQ4EFgQULlrGFPbxwz525ywQYPs72P7YnL4wHwYDVR0jBBgwFoAU0uJLph7MfZta -JndM1uRDMygEEHYwDgYDVR0PAQH/BAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUFBwMC -BggrBgEFBQcDBDANBgkqhkiG9w0BAQsFAAOCAgEAwLc+Xg5Fyfbgu5iFs1y7E0Et -4E/5lF0A4iqDVX3e7/upoUIBFZFv2PlAqIlhQ49NgGlIfrBlwEijZJ9kgVmUcKDS -UrqBvKUn+99dTC8Zn/Py9ofLNcJy+qNJg4TpbpBxXaP1MXdZYXdYkGtyyPIGo31U -oHibNLQDCtKFMoEPCvFuCBtJgyT46l5KN7VQCA0ZDm84fVmIgEEOXWwz0mDIhGWm -hDhmqONznl0+aHirqJxsBaplBaFVV1N02ksR53sPPy/UfDsAD3Fpp8R1DAMEyy0o -kTqm8QINVL961YT1Y/oI+GlypjPq9cL0dEHdxwu6gyCHPMMGGGIDHmLoqJJuj/Kr -/T08jhtDv8D7e9m3wfSW/RqHKE31Yy21SXv/gpcHGunwzDoj/QUvRl/xTjJfx+S8 -2NHxSU8QOdexhJumsNFJe8kH8cRJMCMB8/hfiBpI0QANkUBJ1aaa/p7vZuEKJm+/ -85m3Yz+zn58/Bube06z6QzFeR8Edi+6hXk4/WoHltgXiNowD3d4xI48sPWEbe+QZ -6u60sEdpY2a+3Xwt9m9R2R+sGP3QyDFd9GVaUPt21TeeLdfS3kPqwO2k+UXB8nV3 -Yh1Hvyx67u0tX3wBVe40CNaAu7iW+e4aXjksG2dxk71lNq5CHJCOtbRK4LUArjy5 -cw4KAXWoaR8YIC3BWgg= ------END CERTIFICATE----- diff --git a/_dev/boring/client_rsa.key b/_dev/boring/client_rsa.key deleted file mode 100644 index fb6503e..0000000 --- a/_dev/boring/client_rsa.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDQNCtaUJ+KPKW6 -3PbxpMFP1YOe8Faknnfm38KW3ijae/cKnonG9RXNiR0q5otHb3mDIQHH0lIeJnE+ -Img9V+nCKCYbRH0e8HIAbmuFpBtC332emgFocymzWLXZXHEXLXJqplbqavCscx9X -vXqtnYwDNbHtR+G62WgFh56W6LOINZRIS4Z4kbuQd29S0ZiVtF38SUVYc58BDs5z -xRSMQdayiuSpyKrIARFX8f2GvlFqn8n8RFwULxs15xLi3ViH3xaAi6f8xtwEpDOj -UuxaY5B2ZowGgbyDWZhFs1qnwb/5pBuN9GLXM3TJpbXC2UugEmY2AuPBiBpL/lR7 -Lk1kx1s3AgEDAoIBAQCKzXI8Nb+xfcPR6KShGIDf460UoDnDFE/vP9cPPsXm/U9c -abEvTg6JBhNx7weE9PuswKvajDa+xEt+wZrTj/EsGsQSLai/Svaq9EeubWeB6lO/ -EVZFohvM5c6Q6EtkyPbxxDnxnKBy92o6flHJE7KsznaeL+vR5kVZBRRkmyJazS4s -Z5rbrN9AhSIfyHs9GCQGgsXT6HMsyoJYFastwQ2qj+9L2ypcM8TW+KGzGfJipoJb -l/N/8WHb4ZumA67lfWq4v5JTA5qAUKcfPszEBrUfQ34Tk+73Iiov9f7SXPYxWxVJ -g9PuzfewvJrp6CPv+/mKNt8PmBYkaXlnyjr9tCwLAoGBAPjAVZapQVuIqftcOZtf -Re9fAV9Vvv1FEO8bKJeIsPDlRkdg+TfTMgxhZU0I3P4XdEj7Fa87w4wkA6GkIrOO -W9/usPOYzSdTP5aVEsdGbT8yD2vTST7Aw/GESKTRJA/Fe1PIb5Nz3OijyTusvFE+ -XSR3EXb1myX+2rFS0Wbiz2U5AoGBANZFWoeFzREnBcDG60RayjiTg71E1/T4zhvU -e/w+71FNbLZXBrNqgV20F73xOme/Mb13yr+YgXxIEQfFtR6hRxZ8u1jndEzw66Jf -YfHt7EGVceMV2pdP4md5ebebEj7qICfXPxF9IZicwZG3QMR5u0tvnx40iNMWhW0M -rY4FabPvAoGBAKXVjmRw1j0FxqeS0RI/g/TqAOo5Kf4uC0oSGw+wdfXuLtpApiU3 -drLrmN4F6Klk+DCnY8on17LCrRZtbHe0PT/0dfe7M2+M1Q8ODITZniohX503hinV -1/ZYMG3gwrUuUjfa9Qz36JsX230d0uDUPhhPYPn5EhlUkcuMi5nsikN7AoGBAI7Y -5wUD3gtvWSsvR4LnMXsNAn4t5U37NBKNp/1/SjYznc7kryJHAOkiun6g0Zp/dn5P -3H+7AP2FYK/ZI2nA2g790jtE+DNLR8GU6/aenYEOS+y5PGTf7ET7pnpnYX9GwBqP -f2D+FmW91mEk1dhRJ4efv2l4WzdkWPNdyQlY8SKfAoGAEIWmowo7EpbR5Boxc2o3 -Tl0JbGi1CNJAHtDjEJCd1OxKrMUrK07hOeEKF6y8K/WBuQhFvI2pu16oT4sMal9Z -mEiJdJAFErefPLQGomHLXfq9mDEY13Ug/xAd9aMyYcubIg5XjAqLMrB60HcrLr7Q -2hMCSDdVP2V/F3QVh8DEirE= ------END PRIVATE KEY----- diff --git a/_dev/boring/ecdsa.pem b/_dev/boring/ecdsa.pem deleted file mode 100644 index 3926a1d..0000000 --- a/_dev/boring/ecdsa.pem +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIBbTCCAROgAwIBAgIQZCsHZcs5ZkzV+zC2E6j5RzAKBggqhkjOPQQDAjASMRAw -DgYDVQQKEwdBY21lIENvMB4XDTE2MDkyNDE3NTE1OFoXDTI2MDkyMjE3NTE1OFow -EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDTO -B3IyzjYfKCp2HWy+P3QHxhdBT4AUGYgwTiSEj5phumPIahFNcOSWptN0UzlZvJdN -MMjVmrFYK/FjF4abkNKjSzBJMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggr -BgEFBQcDATAMBgNVHRMBAf8EAjAAMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAKBggq -hkjOPQQDAgNIADBFAiEAp9W157PM1IadPBc33Cbj7vaFvp+rXs/hSuMCzP8pgV8C -IHCswo1qiC0ZjQmWsBlmz5Zbp9rOorIzBYmGRhRdNs3j ------END CERTIFICATE----- ------BEGIN EC PRIVATE KEY----- -MHcCAQEEIFdhO7IW5UIwpB1e2Vunm9QyKvUHWcVwGfLjhpOajuR7oAoGCCqGSM49 -AwEHoUQDQgAENM4HcjLONh8oKnYdbL4/dAfGF0FPgBQZiDBOJISPmmG6Y8hqEU1w -5Jam03RTOVm8l00wyNWasVgr8WMXhpuQ0g== ------END EC PRIVATE KEY----- diff --git a/_dev/boring/httpreq.txt b/_dev/boring/httpreq.txt deleted file mode 100644 index e4e6ac1..0000000 --- a/_dev/boring/httpreq.txt +++ /dev/null @@ -1,5 +0,0 @@ -GET / HTTP/1.1 -Host: example.com -Connection: close - - diff --git a/_dev/boring/rsa.pem b/_dev/boring/rsa.pem deleted file mode 100644 index f5cc584..0000000 --- a/_dev/boring/rsa.pem +++ /dev/null @@ -1,45 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEA1DHcIM3SThFqy8nAkPQFX0E7ph8jqh8EATXryjKHGuVjR3Xh -OQ0BSPoJxyfdg/VEwevFrtmZAfz0WCbxvP2SVCmf7oobg4V2KPSo3nNt9vlBFUne -RtIyHRQ8YRnGSWaRHzJbX6ffltnG2aD+8qUfk161rdZgxBA9G0Ga47IkwQhT2Hqu -H3dW2Uu4W2WMyt6gX/tdyEAV57MOPcoceknr7Nb2kfiuDPR7h6wFrW3I6eoj8oX2 -SkIOuVNt1Z31BAUcPJDUjqopI0o9tolM/7X13M8dEY0OJQVr7FQYDF9JeSYeEMyb -wizjBaHDm48mSghP1o5UssQBbNNC83btXCjiLQIDAQABAoIBACzvGgRAUYaCnbDl -2kdXxUN0luMIuQ6vXrO67WF17bI+XRWm2riwDlObzzJDON9Wsua1vLjYD1SickOw -i4RP1grIfbuPt1/UhT8LAC+LFgA0rBmL+OvaWw5ZWKffQ2QLujN3AG5zKB/Tog43 -z4UmfldAuQxE11zta2M4M0qAUNQnQj1oiuI8RUdG0VvvLw8Htdi1ogH0CI5R669z -NjHt+JV+2gzKx6EX0s8mQL3yXGkC2xXItRbFclyCMJEhPS7QbBu+tru35N6WpzAq -BCl2Q7LQogvSA6MXuMOx6CyuExVfgmhbfeoheLE8gmXwl0Y37n/g6ZBZFAtpCjcs -UckPv0ECgYEA1orl7RwgIsZljMap6vWtMGoRIHKmT91DGpMmkh4suZe+yAk85maU -49Vd+8ZfIN41AH37yrsGOcPHgz5o5QufELpoub6DCsQ7u9F1vQp55cp+qyBWzAgz -b/xUuVnIyv3kLan3fpk7ZGCBXFBpLG0QXMFOHtda3Mlk5SmuoEYaYRkCgYEA/TLR -u4neKqyqwsqMuRJGC1iKFVmfCjZeNMtPNbTWpdqez/vvT8APnEpIumUGt8YROLGZ -8biUr5/ViOkmaP3wmQbO9m2/cE01lMTYv75w1cw2KVQe6kAHJkOx+JEx9xg53RJ/ -QlFtG5MQUy2599Gxp8BMGaXLH5yo4qwvNvY6CDUCgYEArxr7AwX7rKZlZ/sV4HHY -gzVu+R7aY0DibiRATO5X7rrNuhLgI+UCDNqvNLn6FqeGdvpcsmDneeozQwmDL77G -ey7KHyBBcF4tquQQxtRwHX+i1yUz8p+W7AX1WLrRSezjeenJ2QhUE1849hGjZeE2 -g546lq2Kub2enfPhVWsiSLECgYEA72T5QCPeVuLioUH5Q5Kvf1K7W+xcnr9A2xHP -Vqwgtre5qFQ/tFuXZuIlWXbjnyY6aiwhrZYjntm0f7pRgrt2nHj/fafOdVPK8Voc -xU4+SSbHntPWVw0qtVcUEjzVzRauvwMaJ43tZ0DpEnwNdO5i1oTObwF+x+jLFWZP -TdwIinECgYBzjZeCxxOMk5SlPpTsLUtgC+q3m1AavXhUVNEPP2gKMOIPTETPbhbG -LBxB2vVbJiS3J7itQy8gceT89O0vSEZnaTPXiM/Ws1QbkBJ8yW7KI7X4WuzN4Imq -/cLBRXLb8R328U27YyQFNGMjr2tX/+vx5FulJjSloWMRNuFWUngv7w== ------END RSA PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIIC+jCCAeKgAwIBAgIRANBDimJ/ww2tz77qcYIhuZowDQYJKoZIhvcNAQELBQAw -EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xNjA5MjQxNzI5MTlaFw0yNjA5MjIxNzI5 -MTlaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQDUMdwgzdJOEWrLycCQ9AVfQTumHyOqHwQBNevKMoca5WNHdeE5DQFI -+gnHJ92D9UTB68Wu2ZkB/PRYJvG8/ZJUKZ/uihuDhXYo9Kjec232+UEVSd5G0jId -FDxhGcZJZpEfMltfp9+W2cbZoP7ypR+TXrWt1mDEED0bQZrjsiTBCFPYeq4fd1bZ -S7hbZYzK3qBf+13IQBXnsw49yhx6Sevs1vaR+K4M9HuHrAWtbcjp6iPyhfZKQg65 -U23VnfUEBRw8kNSOqikjSj22iUz/tfXczx0RjQ4lBWvsVBgMX0l5Jh4QzJvCLOMF -ocObjyZKCE/WjlSyxAFs00Lzdu1cKOItAgMBAAGjSzBJMA4GA1UdDwEB/wQEAwIF -oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBQGA1UdEQQNMAuC -CWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEAygPV4enmvwSuMd1JarxOXpOK -Z4Nsk7EKlfCPgzxQUOkFdLIr5ZG1kUkQt/omzTmoIWjLAsoYzT0ZCPOrioczKsWj -MceFUIkT0w+eIl+8DzauPy34o8rjcApglF165UG3iphlpI+jdPzv5TBarUAbwsFb -ClMLEiNJQ0OMxAIaRtb2RehD4q3OWlpWf6joJ36PRBqL8T5+f2x6Tg3c64UR+QPX -98UcCQHHdEhm7y2z5Z2Wt0B48tZ+UAxDEoEwMghNyw7wUD79IRlXGYypBnXaMuLX -46aGxbsSQ7Rfg62Co3JG7vo+eJd0AoZHrtFUnfM8V70IFzMBZnSwRslHRJe56Q== ------END CERTIFICATE----- diff --git a/_dev/boring/run.sh b/_dev/boring/run.sh deleted file mode 100755 index 99a8e79..0000000 --- a/_dev/boring/run.sh +++ /dev/null @@ -1,8 +0,0 @@ -#! /bin/sh -set -e - -/boringssl/build/tool/bssl client -grease -min-version tls1.3 -max-version tls1.3 \ - -session-out /session -connect "$@" < /httpreq.txt -exec /boringssl/build/tool/bssl client -grease -min-version tls1.3 -max-version tls1.3 \ - -session-in /session -connect "$@" < /httpreq.txt - diff --git a/_dev/boring/server.sh b/_dev/boring/server.sh deleted file mode 100755 index 7cad11f..0000000 --- a/_dev/boring/server.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -PATH=/boringssl/build/tool:$PATH -set -x - -# RSA -bssl server \ - -key rsa.pem \ - -min-version tls1.2 -max-version tls1.3 \ - -accept 1443 -loop -www 2>&1 & - -# ECDSA -bssl server \ - -key ecdsa.pem \ - -min-version tls1.2 -max-version tls1.3 \ - -accept 2443 -loop -www 2>&1 & - -# Require client authentication (with ECDSA) -bssl server \ - -key ecdsa.pem \ - -min-version tls1.2 -max-version tls1.3 \ - -accept 6443 -loop -www \ - -require-any-client-cert -debug 2>&1 & - -# ECDSA and SIDH/P503-X25519 -bssl server \ - -key ecdsa.pem \ - -curves X25519-SIDHp503:X25519:P-256:P-384:P-521 \ - -min-version tls1.2 -max-version tls1.3 \ - -accept 7443 -loop -www \ - -debug 2>&1 & - -wait diff --git a/_dev/boring/sidh_ff433815b51c34496bb6bea13e73e29e5c278238.patch b/_dev/boring/sidh_ff433815b51c34496bb6bea13e73e29e5c278238.patch deleted file mode 100644 index 545e8b8..0000000 --- a/_dev/boring/sidh_ff433815b51c34496bb6bea13e73e29e5c278238.patch +++ /dev/null @@ -1,5176 +0,0 @@ -diff --git a/CMakeLists.txt b/CMakeLists.txt -index bfde5d588..a0f0da3b2 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -520,6 +520,7 @@ add_subdirectory(ssl/test) - add_subdirectory(fipstools) - add_subdirectory(tool) - add_subdirectory(decrepit) -+add_subdirectory(third_party/sidh) - - if(FUZZ) - add_subdirectory(fuzz) -diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt -index b1ca70e15..7135f55fc 100644 ---- a/crypto/CMakeLists.txt -+++ b/crypto/CMakeLists.txt -@@ -396,6 +396,7 @@ add_library( - ../third_party/fiat/curve25519.c - - $ -+ $ - - ${CRYPTO_ARCH_SOURCES} - ${CRYPTO_FIPS_OBJECTS} -diff --git a/include/openssl/nid.h b/include/openssl/nid.h -index afeb2dea4..effe19205 100644 ---- a/include/openssl/nid.h -+++ b/include/openssl/nid.h -@@ -4234,6 +4234,12 @@ extern "C" { - #define LN_auth_any "auth-any" - #define NID_auth_any 958 - -+#define SN_X25519_SIDHp503 "X25519-SIDHp503" -+/* This ID is only needed by kNamedGroups (ssl_key_share.c). It isn't -+ used in kObjects array (obj_dat.h). It can't be smaller than than -+ NUM_NID (obj_dat.h) -+*/ -+#define NID_X25519_SIDHp503 960 - - #if defined(__cplusplus) - } /* extern C */ -diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h -index 17c559259..9cbf536e1 100644 ---- a/include/openssl/ssl.h -+++ b/include/openssl/ssl.h -@@ -2177,6 +2177,7 @@ OPENSSL_EXPORT int SSL_set1_curves_list(SSL *ssl, const char *curves); - #define SSL_CURVE_SECP384R1 24 - #define SSL_CURVE_SECP521R1 25 - #define SSL_CURVE_X25519 29 -+#define SSL_CURVE_X25519_SIDHp503 0xFE30 - - // SSL_get_curve_id returns the ID of the curve used by |ssl|'s most recently - // completed handshake or 0 if not applicable. -diff --git a/ssl/CMakeLists.txt b/ssl/CMakeLists.txt -index d6c1294f1..8d7cfa14f 100644 ---- a/ssl/CMakeLists.txt -+++ b/ssl/CMakeLists.txt -@@ -1,4 +1,4 @@ --include_directories(../include) -+include_directories(../include ../third_party/sidh/include) - - add_library( - ssl -diff --git a/ssl/handshake_client.cc b/ssl/handshake_client.cc -index c1d54bd8f..d141cc399 100644 ---- a/ssl/handshake_client.cc -+++ b/ssl/handshake_client.cc -@@ -1011,6 +1011,7 @@ static enum ssl_hs_wait_t do_read_server_key_exchange(SSL_HANDSHAKE *hs) { - !hs->peer_key.CopyFrom(point)) { - return ssl_hs_error; - } -+ hs->key_share->SetInitiator(true); - } 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); -diff --git a/ssl/handshake_server.cc b/ssl/handshake_server.cc -index c4f3b75e5..1c93fd16d 100644 ---- a/ssl/handshake_server.cc -+++ b/ssl/handshake_server.cc -@@ -932,7 +932,10 @@ static enum ssl_hs_wait_t do_send_server_certificate(SSL_HANDSHAKE *hs) { - hs->new_session->group_id = group_id; - - // Set up ECDH, generate a key, and emit the public half. -- hs->key_share = SSLKeyShare::Create(group_id); -+ if ((hs->key_share = SSLKeyShare::Create(group_id)) == nullptr) { -+ return ssl_hs_error; -+ } -+ hs->key_share->SetInitiator(false); - if (!hs->key_share || - !CBB_add_u8(cbb.get(), NAMED_CURVE_TYPE) || - !CBB_add_u16(cbb.get(), group_id) || -diff --git a/ssl/internal.h b/ssl/internal.h -index f8a2ea70a..ddd6bb397 100644 ---- a/ssl/internal.h -+++ b/ssl/internal.h -@@ -998,12 +998,20 @@ class SSLKeyShare { - // Deserialize initializes the state of the key exchange from |in|, returning - // true if successful and false otherwise. It is called by |Create|. - virtual bool Deserialize(CBS *in) { return false; } -+ -+ // Sets flag indicating role of the key share owner. True for initiator of the -+ // handshake, false for responder. -+ void SetInitiator(bool flag) { is_initiator_ = flag; } -+ -+ protected: -+ bool is_initiator_ = false; - }; - - struct NamedGroup { - int nid; - uint16_t group_id; -- const char name[8], alias[11]; -+ const char name[16], alias[15]; -+ uint16_t min_protocol_ver; - }; - - // NamedGroups returns all supported groups. -@@ -1019,6 +1027,10 @@ bool ssl_nid_to_group_id(uint16_t *out_group_id, int nid); - // true. Otherwise, it returns false. - bool ssl_name_to_group_id(uint16_t *out_group_id, const char *name, size_t len); - -+// ssl_get_protocol_ver_for_group looks up the minimal version of a TLS that -+// supports |group_id|. In case |group_id| is not a valid ID of a group function -+// returns 0. -+uint16_t ssl_get_protocol_ver_for_group(uint16_t group_id); - - // Handshake messages. - -diff --git a/ssl/ssl_key_share.cc b/ssl/ssl_key_share.cc -index 55c74633c..f36e33bb5 100644 ---- a/ssl/ssl_key_share.cc -+++ b/ssl/ssl_key_share.cc -@@ -30,6 +30,8 @@ - #include "internal.h" - #include "../crypto/internal.h" - -+#include "sidh/def_p503.h" -+#include "sidh/P503_api.h" - - BSSL_NAMESPACE_BEGIN - -@@ -207,12 +209,88 @@ class X25519KeyShare : public SSLKeyShare { - uint8_t private_key_[32]; - }; - -+class SIDHp503X25519KeyShare : public SSLKeyShare { -+public: -+ ~SIDHp503X25519KeyShare() override { -+ OPENSSL_cleanse(private_x25519_, sizeof(private_x25519_)); -+ OPENSSL_cleanse(private_SIDH_, sizeof(private_SIDH_)); -+ } -+ -+ uint16_t GroupID() const override { -+ return SSL_CURVE_X25519_SIDHp503; -+ } -+ -+ bool Offer(CBB *out) override { -+ uint8_t public_x25519[32] = {0}; -+ uint8_t public_SIDH[SIDHp503_PUB_BYTESZ] = {0}; -+ -+ X25519_keypair(public_x25519, private_x25519_); -+ if (EphemeralKeyPair_SIDHp503(private_SIDH_, public_SIDH, is_initiator_)) { -+ return false; -+ } -+ -+ return -+ CBB_add_bytes(out, public_x25519, sizeof(public_x25519)) && -+ CBB_add_bytes(out, public_SIDH, sizeof(public_SIDH)); -+ } -+ -+ bool Finish(Array *out_secret, uint8_t *out_alert, -+ Span peer_key) override { -+ *out_alert = SSL_AD_INTERNAL_ERROR; -+ -+ Array secret; -+ if (!secret.Init(sizeof(private_x25519_) + SIDHp503_SS_BYTESZ)) { -+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); -+ return false; -+ } -+ -+ if (peer_key.size() != (32 + SIDHp503_PUB_BYTESZ) || -+ !X25519(secret.data(), private_x25519_, peer_key.data())) { -+ *out_alert = SSL_AD_DECODE_ERROR; -+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); -+ return false; -+ } -+ -+ if (is_initiator_) { -+ // Never fails -+ (void)EphemeralSecretAgreement_A_SIDHp503(private_SIDH_, peer_key.data() + 32, secret.data() + sizeof(private_x25519_)); -+ } else { -+ (void)EphemeralSecretAgreement_B_SIDHp503(private_SIDH_, peer_key.data() + 32, secret.data() + sizeof(private_x25519_)); -+ } -+ -+ *out_secret = std::move(secret); -+ return true; -+ } -+ -+ bool Serialize(CBB *out) override { -+ return (CBB_add_asn1_uint64(out, GroupID()) && -+ CBB_add_asn1_octet_string(out, private_x25519_, sizeof(private_x25519_)) && -+ CBB_add_asn1_octet_string(out, private_SIDH_, sizeof(private_SIDH_))); -+ } -+ -+ bool Deserialize(CBS *in) override { -+ CBS key; -+ if (!CBS_get_asn1(in, &key, CBS_ASN1_OCTETSTRING) || -+ CBS_len(&key) != (sizeof(private_x25519_) + sizeof(private_SIDH_)) || -+ !CBS_copy_bytes(&key, private_x25519_, sizeof(private_x25519_)) || -+ !CBS_copy_bytes(&key, private_SIDH_, sizeof(private_SIDH_))) { -+ return false; -+ } -+ return true; -+ } -+ -+private: -+ uint8_t private_x25519_[32]; -+ uint8_t private_SIDH_[SIDHp503_PRV_KEY_BYTESZ_MAX]; -+}; -+ - CONSTEXPR_ARRAY 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_secp224r1, SSL_CURVE_SECP224R1, "P-224", "secp224r1", TLS1_VERSION}, -+ {NID_X9_62_prime256v1, SSL_CURVE_SECP256R1, "P-256", "prime256v1", TLS1_VERSION}, -+ {NID_secp384r1, SSL_CURVE_SECP384R1, "P-384", "secp384r1", TLS1_VERSION}, -+ {NID_secp521r1, SSL_CURVE_SECP521R1, "P-521", "secp521r1", TLS1_VERSION}, -+ {NID_X25519, SSL_CURVE_X25519, "X25519", "x25519", TLS1_VERSION}, -+ {NID_X25519_SIDHp503, SSL_CURVE_X25519_SIDHp503, "X25519-SIDHp503", "x25519sidhp503", TLS1_3_VERSION}, - }; - - } // namespace -@@ -237,6 +315,8 @@ UniquePtr SSLKeyShare::Create(uint16_t group_id) { - New(NID_secp521r1, SSL_CURVE_SECP521R1)); - case SSL_CURVE_X25519: - return UniquePtr(New()); -+ case SSL_CURVE_X25519_SIDHp503: -+ return UniquePtr(New()); - default: - return nullptr; - } -@@ -288,6 +368,15 @@ bool ssl_name_to_group_id(uint16_t *out_group_id, const char *name, size_t len) - return false; - } - -+uint16_t ssl_get_protocol_ver_for_group(uint16_t group_id) { -+ for (const auto &group : kNamedGroups) { -+ if (group.group_id == group_id) { -+ return group.min_protocol_ver; -+ } -+ } -+ return 0; -+} -+ - BSSL_NAMESPACE_END - - using namespace bssl; -diff --git a/ssl/t1_lib.cc b/ssl/t1_lib.cc -index 678e4a3b7..6bfd21c82 100644 ---- a/ssl/t1_lib.cc -+++ b/ssl/t1_lib.cc -@@ -324,7 +324,8 @@ bool tls1_get_shared_group(SSL_HANDSHAKE *hs, uint16_t *out_group_id) { - - for (uint16_t pref_group : pref) { - for (uint16_t supp_group : supp) { -- if (pref_group == supp_group) { -+ if ((pref_group == supp_group) && -+ (ssl_get_protocol_ver_for_group(pref_group)<=ssl_protocol_version(ssl))) { - *out_group_id = pref_group; - return true; - } -@@ -2177,7 +2178,10 @@ static bool ext_key_share_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { - group_id = groups[0]; - } - -- hs->key_share = SSLKeyShare::Create(group_id); -+ if ((hs->key_share = SSLKeyShare::Create(group_id)) == nullptr) { -+ return false; -+ } -+ hs->key_share->SetInitiator(true); - CBB key_exchange; - if (!hs->key_share || - !CBB_add_u16(&kse_bytes, group_id) || -diff --git a/third_party/sidh/CMakeLists.txt b/third_party/sidh/CMakeLists.txt -new file mode 100644 -index 000000000..6befbfe47 ---- /dev/null -+++ b/third_party/sidh/CMakeLists.txt -@@ -0,0 +1,54 @@ -+cmake_minimum_required(VERSION 2.8.11) -+include_directories(../../include) -+ -+set(ASM_EXT S) -+enable_language(ASM) -+add_definitions(-pedantic) -+ -+# Compile to object files, we will link them with libssl -+add_library( -+ sidh -+ -+ OBJECT -+ -+ src/ec_isogeny.c -+ src/fpx.c -+ src/P503.c -+ src/sidh.c -+) -+ -+# Architecture specific settings -+if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64" OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm64") -+ add_definitions(-lrt) -+endif() -+ -+# Platform specific sources -+if(OPENSSL_NO_ASM) -+ target_sources( -+ sidh -+ PRIVATE -+ src/generic/fp_generic.c -+ ) -+elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64") -+ target_sources( -+ sidh -+ -+ PRIVATE -+ -+ src/AMD64/fp_x64.c -+ src/AMD64/fp_x64_asm.${ASM_EXT} -+ ) -+elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64" OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm64") -+ target_sources( -+ sidh -+ -+ PRIVATE -+ -+ src/ARM64/fp_arm64.c -+ src/ARM64/fp_arm64_asm.${ASM_EXT} -+ ) -+endif() -+ -+target_include_directories(sidh PUBLIC -+ include -+) -diff --git a/third_party/sidh/LICENSE b/third_party/sidh/LICENSE -new file mode 100644 -index 000000000..d76bde897 ---- /dev/null -+++ b/third_party/sidh/LICENSE -@@ -0,0 +1,56 @@ -+MIT License -+ -+Copyright (c) Microsoft Corporation. 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 -+ -+======================================================================== -+ -+Performance improvements and aligning the code to nicely fit to -+BoringSSL was done by Cloudflare and is licensed under BSD3 licence. -+ -+======================================================================== -+ -+Copyright (c) 2018 Cloudflare. All rights reserved. -+ -+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 Cloudflare 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. -diff --git a/third_party/sidh/include/sidh/P503_api.h b/third_party/sidh/include/sidh/P503_api.h -new file mode 100644 -index 000000000..6b25196a5 ---- /dev/null -+++ b/third_party/sidh/include/sidh/P503_api.h -@@ -0,0 +1,65 @@ -+/******************************************************************************************** -+* SIDH: an efficient supersingular isogeny cryptography library -+* -+* Abstract: API header file for P503 -+*********************************************************************************************/ -+ -+#ifndef P503_API_H__ -+#define P503_API_H__ -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/*********************** Ephemeral key exchange API ***********************/ -+ -+// Encoding of keys for KEX-based isogeny system "SIDHp503" (wire format): -+// ---------------------------------------------------------------------- -+// Elements over GF(p503) are encoded in 63 octets in little endian format (i.e., the least significant octet is located in the lowest memory address). -+// Elements (a+b*i) over GF(p503^2), where a and b are defined over GF(p503), are encoded as {a, b}, with a in the lowest memory portion. -+// -+// Private keys PrivateKeyA and PrivateKeyB can have values in the range [0, 2^250-1] and [0, 2^252-1], resp. In the SIDH API, private keys are encoded -+// in 32 octets in little endian format. -+// Public keys PublicKeyA and PublicKeyB consist of 3 elements in GF(p503^2). In the SIDH API, they are encoded in 378 octets. -+// Shared keys SharedSecretA and SharedSecretB consist of one element in GF(p503^2). In the SIDH API, they are encoded in 126 octets. -+ -+// SECURITY NOTE: SIDH supports ephemeral Diffie-Hellman key exchange. It is NOT secure to use it with static keys. -+// See "On the Security of Supersingular Isogeny Cryptosystems", S.D. Galbraith, C. Petit, B. Shani and Y.B. Ti, in ASIACRYPT 2016, 2016. -+// Extended version available at: http://eprint.iacr.org/2016/859 -+ -+// Alice's ephemeral public key generation -+// Input: a private key PrivateKeyA in the range [0, 2^250 - 1], stored in 32 bytes. -+// Output: the public key PublicKeyA consisting of 3 GF(p503^2) elements encoded in 378 bytes. -+int EphemeralKeyGeneration_A_SIDHp503(const unsigned char* PrivateKeyA, unsigned char* PublicKeyA); -+ -+// Bob's ephemeral key-pair generation -+// It produces a private key PrivateKeyB and computes the public key PublicKeyB. -+// The private key is an integer in the range [0, 2^Floor(Log(2,3^159)) - 1], stored in 32 bytes. -+// The public key consists of 3 GF(p503^2) elements encoded in 378 bytes. -+int EphemeralKeyGeneration_B_SIDHp503(const unsigned char* PrivateKeyB, unsigned char* PublicKeyB); -+ -+// Alice's ephemeral shared secret computation -+// It produces a shared secret key SharedSecretA using her secret key PrivateKeyA and Bob's public key PublicKeyB -+// Inputs: Alice's PrivateKeyA is an integer in the range [0, 2^250 - 1], stored in 32 bytes. -+// Bob's PublicKeyB consists of 3 GF(p503^2) elements encoded in 378 bytes. -+// Output: a shared secret SharedSecretA that consists of one element in GF(p503^2) encoded in 126 bytes. -+int EphemeralSecretAgreement_A_SIDHp503(const unsigned char* PrivateKeyA, const unsigned char* PublicKeyB, unsigned char* SharedSecretA); -+ -+// Bob's ephemeral shared secret computation -+// It produces a shared secret key SharedSecretB using his secret key PrivateKeyB and Alice's public key PublicKeyA -+// Inputs: Bob's PrivateKeyB is an integer in the range [0, 2^Floor(Log(2,3^159)) - 1], stored in 32 bytes. -+// Alice's PublicKeyA consists of 3 GF(p503^2) elements encoded in 378 bytes. -+// Output: a shared secret SharedSecretB that consists of one element in GF(p503^2) encoded in 126 bytes. -+int EphemeralSecretAgreement_B_SIDHp503(const unsigned char* PrivateKeyB, const unsigned char* PublicKeyA, unsigned char* SharedSecretB); -+ -+// Generates SIDH/P503 key pair. Internally uses BN_rand() for a entropy source. -+// Input: IsInitiator: 1 for generating public key type A, 0 for type B. -+// Output: the private (PrivateKey) stored in 32 bytes, public key (PublicKey) stored in 378 bytes -+// Returns: 0 on succes, -1 in case of failure -+int EphemeralKeyPair_SIDHp503(unsigned char* PrivateKey, unsigned char* PublicKey, int IsInitiator); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif -diff --git a/third_party/sidh/include/sidh/def_p503.h b/third_party/sidh/include/sidh/def_p503.h -new file mode 100644 -index 000000000..1f39f5988 ---- /dev/null -+++ b/third_party/sidh/include/sidh/def_p503.h -@@ -0,0 +1,70 @@ -+#ifndef DEF_P503_H_ -+#define DEF_P503_H_ -+ -+#include -+#include "openssl/base.h" -+#include "../crypto/internal.h" -+#include "sidh/P503_api.h" -+ -+// Basic constants -+#define SIDHp503_PRV_A_BITSZ 250 // Bit size of SIDH private key (type A) -+#define SIDHp503_PRV_B_BITSZ 252 // Bit size of SIDH private key (type B) -+#define SIDHp503_PUB_BYTESZ 378 // Byte size of SIDH public key -+#define SIDHp503_SS_BYTESZ 126 // Shared secret byte size -+#define SIDHp503_PRV_KEY_BYTESZ_MAX (((SIDHp503_PRV_A_BITSZ>SIDHp503_PRV_B_BITSZ?SIDHp503_PRV_B_BITSZ:SIDHp503_PRV_B_BITSZ)+7)/8) -+#define NBITS_FIELD 503 -+#define NBITS_ORDER 256 -+#define NWORDS_ORDER ((NBITS_ORDER+RADIX-1)/RADIX) // Number of words of oA and oB, where oA and oB are the subgroup orders of Alice and Bob, resp. -+#define NWORDS64_FIELD ((NBITS_FIELD+63)/64) // Number of 64-bit words of a 503-bit field element -+#define NWORDS64_ORDER ((NBITS_ORDER+63)/64) // Number of 64-bit words of a 256-bit element -+#define MAX_Alice 125 -+#define MAX_Bob 159 -+#define RADIX64 64 -+ -+#if defined(OPENSSL_64_BIT) -+ #define NWORDS_FIELD 8 // Number of words of a 503-bit field element -+ #define p503_ZERO_WORDS 3 // Number of "0" digits in the least significant part of p503 + 1 -+ #define RADIX 64 -+ #define LOG2RADIX 6 -+ typedef uint64_t digit_t; // Unsigned 64-bit digit -+#else -+ #define NWORDS_FIELD 16 -+ #define p503_ZERO_WORDS 7 -+ #define RADIX 32 -+ #define LOG2RADIX 5 -+ typedef uint32_t digit_t; // Unsigned 32-bit digit -+#endif -+ -+// Extended datatype support -+#if !defined(BORINGSSL_HAS_UINT128) -+ typedef uint64_t uint128_t[2]; -+#endif -+ -+struct params_t { -+ const uint64_t prime[NWORDS64_FIELD]; -+ const uint64_t primeP1[NWORDS64_FIELD]; -+ const uint64_t primeX2[NWORDS64_FIELD]; -+ // Order of Alice's subgroup -+ const uint64_t Alice_order[NWORDS64_ORDER]; -+ // Order of Bob's subgroup -+ const uint64_t Bob_order[NWORDS64_ORDER]; -+ // Alice's generator values {XPA0 + XPA1*i, XQA0, XRA0 + XRA1*i} in GF(p503^2), expressed in Montgomery representation -+ const uint64_t A_gen[5*NWORDS64_FIELD]; -+ // Bob's generator values {XPB0 + XPB1*i, XQB0, XRB0 + XRB1*i} in GF(p503^2), expressed in Montgomery representation -+ const uint64_t B_gen[5*NWORDS64_FIELD]; -+ // Montgomery constant Montgomery_R2 = (2^512)^2 mod p503 -+ const uint64_t Montgomery_R2[NWORDS64_FIELD]; -+ // Value one in Montgomery representation -+ const uint64_t Montgomery_one[NWORDS64_FIELD]; -+ // Value (2^256)^2 mod 3^159 -+ const uint64_t Montgomery_Rprime[NWORDS64_ORDER]; -+ // Value -(3^159)^-1 mod 2^256 -+ const uint64_t Montgomery_rprime[NWORDS64_ORDER]; -+ // Value order_Bob/3 mod p503 -+ const uint64_t Border_div3[NWORDS_ORDER]; -+ // Fixed parameters for isogeny tree computation -+ const unsigned int strat_Alice[MAX_Alice-1]; -+ const unsigned int strat_Bob[MAX_Bob-1]; -+}; -+ -+#endif // DEF_P503_H_ -diff --git a/third_party/sidh/src/AMD64/fp_x64.c b/third_party/sidh/src/AMD64/fp_x64.c -new file mode 100644 -index 000000000..62bb9692e ---- /dev/null -+++ b/third_party/sidh/src/AMD64/fp_x64.c -@@ -0,0 +1,88 @@ -+/******************************************************************************************** -+* SIDH: an efficient supersingular isogeny cryptography library -+* -+* Abstract: modular arithmetic optimized for x64 platforms for P503 -+*********************************************************************************************/ -+ -+#include "../internal.h" -+#include "../P503_internal.h" -+ -+// Global constants -+extern const struct params_t kP503Params; -+ -+inline void fpadd503(const digit_t* a, const digit_t* b, digit_t* c) -+{ // Modular addition, c = a+b mod p503. -+ // Inputs: a, b in [0, 2*p503-1] -+ // Output: c in [0, 2*p503-1] -+ -+ fpadd503_asm(a, b, c); -+} -+ -+ -+inline void fpsub503(const digit_t* a, const digit_t* b, digit_t* c) -+{ // Modular subtraction, c = a-b mod p503. -+ // Inputs: a, b in [0, 2*p503-1] -+ // Output: c in [0, 2*p503-1] -+ fpsub503_asm(a, b, c); -+} -+ -+ -+inline void fpneg503(digit_t* a) -+{ // Modular negation, a = -a mod p503. -+ // Input/output: a in [0, 2*p503-1] -+ unsigned int i, borrow = 0; -+ -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ SUBC(borrow, ((digit_t*)kP503Params.primeX2)[i], a[i], borrow, a[i]); -+ } -+} -+ -+ -+void fpdiv2_503(const digit_t* a, digit_t* c) -+{ // Modular division by two, c = a/2 mod p503. -+ // Input : a in [0, 2*p503-1] -+ // Output: c in [0, 2*p503-1] -+ unsigned int i, carry = 0; -+ digit_t mask; -+ -+ mask = 0 - (digit_t)(a[0] & 1); // If a is odd compute a+p503 -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ ADDC(carry, a[i], ((digit_t*)kP503Params.prime)[i] & mask, carry, c[i]); -+ } -+ -+ mp_shiftr1(c, NWORDS_FIELD); -+} -+ -+ -+void fpcorrection503(digit_t* a) -+{ // Modular correction to reduce field element a in [0, 2*p503-1] to [0, p503-1]. -+ unsigned int i, borrow = 0; -+ digit_t mask; -+ -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ SUBC(borrow, a[i], ((digit_t*)kP503Params.prime)[i], borrow, a[i]); -+ } -+ mask = 0 - (digit_t)borrow; -+ -+ borrow = 0; -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ ADDC(borrow, a[i], ((digit_t*)kP503Params.prime)[i] & mask, borrow, a[i]); -+ } -+} -+ -+ -+void mp_mul(const digit_t* a, const digit_t* b, digit_t* c, const unsigned int nwords) -+{ // Multiprecision multiply, c = a*b, where lng(a) = lng(b) = nwords. -+ -+ UNREFERENCED_PARAMETER(nwords); -+ mul503_asm(a, b, c); -+} -+ -+ -+void rdc_mont(const digit_t* ma, digit_t* mc) -+{ // Montgomery reduction exploiting special form of the prime. -+ // mc = ma*R^-1 mod primeX2, where R = 2^512. -+ // If ma < 2^512*p503, the output mc is in the range [0, 2*p503-1]. -+ // ma is assumed to be in Montgomery representation. -+ rdc503_asm(ma, mc); -+} -diff --git a/third_party/sidh/src/AMD64/fp_x64_asm.S b/third_party/sidh/src/AMD64/fp_x64_asm.S -new file mode 100644 -index 000000000..4e8f3147a ---- /dev/null -+++ b/third_party/sidh/src/AMD64/fp_x64_asm.S -@@ -0,0 +1,1640 @@ -+//******************************************************************************************* -+// SIDH: an efficient supersingular isogeny cryptography library -+// -+// Abstract: field arithmetic in x64 assembly for P503 on Linux -+//******************************************************************************************* -+ -+.intel_syntax noprefix -+ -+// Registers that are used for parameter passing: -+#define reg_p1 rdi -+#define reg_p2 rsi -+#define reg_p3 rdx -+ -+// p503 + 1 -+#define p503p1_3 0xAC00000000000000 -+#define p503p1_4 0x13085BDA2211E7A0 -+#define p503p1_5 0x1B9BF6C87B7E7DAF -+#define p503p1_6 0x6045C6BDDA77A4D0 -+#define p503p1_7 0x004066F541811E1E -+// p503 x 2 -+#define p503x2_0 0xFFFFFFFFFFFFFFFE -+#define p503x2_1 0xFFFFFFFFFFFFFFFF -+#define p503x2_3 0x57FFFFFFFFFFFFFF -+#define p503x2_4 0x2610B7B44423CF41 -+#define p503x2_5 0x3737ED90F6FCFB5E -+#define p503x2_6 0xC08B8D7BB4EF49A0 -+#define p503x2_7 0x0080CDEA83023C3C -+ -+.text -+ -+.extern OPENSSL_ia32cap_P -+.hidden OPENSSL_ia32cap_P -+ -+p503p1_nz: -+.quad 0xAC00000000000000 -+.quad 0x13085BDA2211E7A0 -+.quad 0x1B9BF6C87B7E7DAF -+.quad 0x6045C6BDDA77A4D0 -+.quad 0x004066F541811E1E -+ -+.macro CSWAP16 IDX, M1, M2 -+ movdqu xmm0, [\M1+\IDX*16] -+ movdqu xmm1, [\M2+\IDX*16] -+ movdqa xmm2, xmm1 -+ pxor xmm2, xmm0 -+ pand xmm2, xmm15 -+ pxor xmm0, xmm2 -+ pxor xmm1, xmm2 -+ movdqu [\M1+\IDX*16], xmm0 -+ movdqu [\M2+\IDX*16], xmm1 -+.endm -+ -+.global cswap503_asm -+cswap503_asm: -+ // Fill xmm15. After this step first half of XMM15 is -+ // just zeros and second half is whatever in RDX -+ movq xmm15, rdx -+ -+ // Copy lower double word everywhere else. So that -+ // XMM15=RDX|RDX. As RDX has either all bits set -+ // or non result will be that XMM15 has also either -+ // all bits set or non of them. 68 = 01000100b -+ pshufd xmm15, xmm15, 68 -+ -+ // P[0].X with Q[0].X -+ CSWAP16 0, rdi, rsi -+ CSWAP16 1, rdi, rsi -+ CSWAP16 2, rdi, rsi -+ CSWAP16 3, rdi, rsi -+ -+ // P[0].Z with Q[0].Z -+ CSWAP16 4, rdi, rsi -+ CSWAP16 5, rdi, rsi -+ CSWAP16 6, rdi, rsi -+ CSWAP16 7, rdi, rsi -+ -+ // P[1].X with Q[1].X -+ CSWAP16 8, rdi, rsi -+ CSWAP16 9, rdi, rsi -+ CSWAP16 10, rdi, rsi -+ CSWAP16 11, rdi, rsi -+ -+ // P[1].Z with Q[1].Z -+ CSWAP16 12, rdi, rsi -+ CSWAP16 13, rdi, rsi -+ CSWAP16 14, rdi, rsi -+ CSWAP16 15, rdi, rsi -+ -+ ret -+ -+//*********************************************************************** -+// Field addition -+// Operation: c [reg_p3] = a [reg_p1] + b [reg_p2] -+//*********************************************************************** -+.global fpadd503_asm -+fpadd503_asm: -+ push r12 -+ push r13 -+ push r14 -+ push r15 -+ -+ xor rax, rax -+ mov r8, [reg_p1] -+ mov r9, [reg_p1+8] -+ mov r10, [reg_p1+16] -+ mov r11, [reg_p1+24] -+ mov r12, [reg_p1+32] -+ mov r13, [reg_p1+40] -+ mov r14, [reg_p1+48] -+ mov r15, [reg_p1+56] -+ add r8, [reg_p2] -+ adc r9, [reg_p2+8] -+ adc r10, [reg_p2+16] -+ adc r11, [reg_p2+24] -+ adc r12, [reg_p2+32] -+ adc r13, [reg_p2+40] -+ adc r14, [reg_p2+48] -+ adc r15, [reg_p2+56] -+ -+ mov rcx, p503x2_0 -+ sub r8, rcx -+ mov rcx, p503x2_1 -+ sbb r9, rcx -+ sbb r10, rcx -+ mov rcx, p503x2_3 -+ sbb r11, rcx -+ mov rcx, p503x2_4 -+ sbb r12, rcx -+ mov rcx, p503x2_5 -+ sbb r13, rcx -+ mov rcx, p503x2_6 -+ sbb r14, rcx -+ mov rcx, p503x2_7 -+ sbb r15, rcx -+ sbb rax, 0 -+ -+ mov rdi, p503x2_0 -+ and rdi, rax -+ mov rsi, p503x2_1 -+ and rsi, rax -+ mov rcx, p503x2_3 -+ and rcx, rax -+ -+ add r8, rdi -+ adc r9, rsi -+ adc r10, rsi -+ adc r11, rcx -+ mov [reg_p3], r8 -+ mov [reg_p3+8], r9 -+ mov [reg_p3+16], r10 -+ mov [reg_p3+24], r11 -+ setc cl -+ -+ mov r8, p503x2_4 -+ and r8, rax -+ mov r9, p503x2_5 -+ and r9, rax -+ mov r10, p503x2_6 -+ and r10, rax -+ mov r11, p503x2_7 -+ and r11, rax -+ -+ bt rcx, 0 -+ adc r12, r8 -+ adc r13, r9 -+ adc r14, r10 -+ adc r15, r11 -+ mov [reg_p3+32], r12 -+ mov [reg_p3+40], r13 -+ mov [reg_p3+48], r14 -+ mov [reg_p3+56], r15 -+ -+ pop r15 -+ pop r14 -+ pop r13 -+ pop r12 -+ ret -+ -+ -+//*********************************************************************** -+// Field subtraction -+// Operation: c [reg_p3] = a [reg_p1] - b [reg_p2] -+//*********************************************************************** -+.global fpsub503_asm -+fpsub503_asm: -+ push r12 -+ push r13 -+ push r14 -+ push r15 -+ -+ xor rax, rax -+ mov r8, [reg_p1] -+ mov r9, [reg_p1+8] -+ mov r10, [reg_p1+16] -+ mov r11, [reg_p1+24] -+ mov r12, [reg_p1+32] -+ mov r13, [reg_p1+40] -+ mov r14, [reg_p1+48] -+ mov r15, [reg_p1+56] -+ sub r8, [reg_p2] -+ sbb r9, [reg_p2+8] -+ sbb r10, [reg_p2+16] -+ sbb r11, [reg_p2+24] -+ sbb r12, [reg_p2+32] -+ sbb r13, [reg_p2+40] -+ sbb r14, [reg_p2+48] -+ sbb r15, [reg_p2+56] -+ sbb rax, 0 -+ -+ mov rdi, p503x2_0 -+ and rdi, rax -+ mov rsi, p503x2_1 -+ and rsi, rax -+ mov rcx, p503x2_3 -+ and rcx, rax -+ -+ add r8, rdi -+ adc r9, rsi -+ adc r10, rsi -+ adc r11, rcx -+ mov [reg_p3], r8 -+ mov [reg_p3+8], r9 -+ mov [reg_p3+16], r10 -+ mov [reg_p3+24], r11 -+ setc cl -+ -+ mov r8, p503x2_4 -+ and r8, rax -+ mov r9, p503x2_5 -+ and r9, rax -+ mov r10, p503x2_6 -+ and r10, rax -+ mov r11, p503x2_7 -+ and r11, rax -+ -+ bt rcx, 0 -+ adc r12, r8 -+ adc r13, r9 -+ adc r14, r10 -+ adc r15, r11 -+ mov [reg_p3+32], r12 -+ mov [reg_p3+40], r13 -+ mov [reg_p3+48], r14 -+ mov [reg_p3+56], r15 -+ -+ pop r15 -+ pop r14 -+ pop r13 -+ pop r12 -+ ret -+ -+ -+///////////////////////////////////////////////////////////////// MACRO -+// Schoolbook integer multiplication, a full row at a time -+// Inputs: memory pointers M0 and M1 -+// Outputs: memory pointer C -+// Temps: regs T0:T9 -+///////////////////////////////////////////////////////////////// -+ -+.macro MUL256_SCHOOL M0, M1, C, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 -+ mov rdx, \M0 -+ mulx \T0, \T1, \M1 // T0:T1 = A0*B0 -+ mov \C, \T1 // C0_final -+ mulx \T1, \T2, 8\M1 // T1:T2 = A0*B1 -+ xor rax, rax -+ adox \T0, \T2 -+ mulx \T2, \T3, 16\M1 // T2:T3 = A0*B2 -+ adox \T1, \T3 -+ mulx \T3, \T4, 24\M1 // T3:T4 = A0*B3 -+ adox \T2, \T4 -+ -+ mov rdx, 8\M0 -+ mulx \T5, \T4, \M1 // T5:T4 = A1*B0 -+ adox \T3, rax -+ xor rax, rax -+ mulx \T6, \T7, 8\M1 // T6:T7 = A1*B1 -+ adox \T4, \T0 -+ mov 8\C, \T4 // C1_final -+ adcx \T5, \T7 -+ mulx \T7, \T8, 16\M1 // T7:T8 = A1*B2 -+ adcx \T6, \T8 -+ adox \T5, \T1 -+ mulx \T8, \T9, 24\M1 // T8:T9 = A1*B3 -+ adcx \T7, \T9 -+ adcx \T8, rax -+ adox \T6, \T2 -+ -+ mov rdx, 16\M0 -+ mulx \T1, \T0, \M1 // T1:T0 = A2*B0 -+ adox \T7, \T3 -+ adox \T8, rax -+ xor rax, rax -+ mulx \T2, \T3, 8\M1 // T2:T3 = A2*B1 -+ adox \T0, \T5 -+ mov 16\C, \T0 // C2_final -+ adcx \T1, \T3 -+ mulx \T3, \T4, 16\M1 // T3:T4 = A2*B2 -+ adcx \T2, \T4 -+ adox \T1, \T6 -+ mulx \T4,\T9, 24\M1 // T3:T4 = A2*B3 -+ adcx \T3, \T9 -+ mov rdx, 24\M0 -+ adcx \T4, rax -+ -+ adox \T2, \T7 -+ adox \T3, \T8 -+ adox \T4, rax -+ -+ mulx \T5, \T0, \M1 // T5:T0 = A3*B0 -+ xor rax, rax -+ mulx \T6, \T7, 8\M1 // T6:T7 = A3*B1 -+ adcx \T5, \T7 -+ adox \T1, \T0 -+ mulx \T7, \T8, 16\M1 // T7:T8 = A3*B2 -+ adcx \T6, \T8 -+ adox \T2, \T5 -+ mulx \T8, \T9, 24\M1 // T8:T9 = A3*B3 -+ adcx \T7, \T9 -+ adcx \T8, rax -+ -+ adox \T3, \T6 -+ adox \T4, \T7 -+ adox \T8, rax -+ mov 24\C, \T1 // C3_final -+ mov 32\C, \T2 // C4_final -+ mov 40\C, \T3 // C5_final -+ mov 48\C, \T4 // C6_final -+ mov 56\C, \T8 // C7_final -+.endm -+ -+//***************************************************************************** -+// 503-bit multiplication using Karatsuba (one level), schoolbook (one level) -+//***************************************************************************** -+mul503_mulx_asm: -+ push r12 -+ push r13 -+ push r14 -+ push r15 -+ mov rcx, reg_p3 -+ -+ // r8-r11 <- AH + AL, rax <- mask -+ xor rax, rax -+ mov r8, [reg_p1] -+ mov r9, [reg_p1+8] -+ mov r10, [reg_p1+16] -+ mov r11, [reg_p1+24] -+ push rbx -+ push rbp -+ sub rsp, 96 -+ add r8, [reg_p1+32] -+ adc r9, [reg_p1+40] -+ adc r10, [reg_p1+48] -+ adc r11, [reg_p1+56] -+ sbb rax, 0 -+ mov [rsp], r8 -+ mov [rsp+8], r9 -+ mov [rsp+16], r10 -+ mov [rsp+24], r11 -+ -+ // r12-r15 <- BH + BL, rbx <- mask -+ xor rbx, rbx -+ mov r12, [reg_p2] -+ mov r13, [reg_p2+8] -+ mov r14, [reg_p2+16] -+ mov r15, [reg_p2+24] -+ add r12, [reg_p2+32] -+ adc r13, [reg_p2+40] -+ adc r14, [reg_p2+48] -+ adc r15, [reg_p2+56] -+ sbb rbx, 0 -+ mov [rsp+32], r12 -+ mov [rsp+40], r13 -+ mov [rsp+48], r14 -+ mov [rsp+56], r15 -+ -+ // r12-r15 <- masked (BH + BL) -+ and r12, rax -+ and r13, rax -+ and r14, rax -+ and r15, rax -+ -+ // r8-r11 <- masked (AH + AL) -+ and r8, rbx -+ and r9, rbx -+ and r10, rbx -+ and r11, rbx -+ -+ // r8-r11 <- masked (AH + AL) + masked (AH + AL) -+ add r8, r12 -+ adc r9, r13 -+ adc r10, r14 -+ adc r11, r15 -+ mov [rsp+64], r8 -+ mov [rsp+72], r9 -+ mov [rsp+80], r10 -+ mov [rsp+88], r11 -+ -+ // [rcx+64] <- (AH+AL) x (BH+BL), low part -+ MUL256_SCHOOL [rsp], [rsp+32], [rcx+64], r8, r9, r10, r11, r12, r13, r14, r15, rbx, rbp -+ -+ // [rcx] <- AL x BL -+ MUL256_SCHOOL [reg_p1], [reg_p2], [rcx], r8, r9, r10, r11, r12, r13, r14, r15, rbx, rbp // Result C0-C3 -+ -+ // [rsp] <- AH x BH -+ MUL256_SCHOOL [reg_p1+32], [reg_p2+32], [rsp], r8, r9, r10, r11, r12, r13, r14, r15, rbx, rbp -+ -+ // r8-r11 <- (AH+AL) x (BH+BL), final step -+ mov r8, [rsp+64] -+ mov r9, [rsp+72] -+ mov r10, [rsp+80] -+ mov r11, [rsp+88] -+ mov rax, [rcx+96] -+ add r8, rax -+ mov rax, [rcx+104] -+ adc r9, rax -+ mov rax, [rcx+112] -+ adc r10, rax -+ mov rax, [rcx+120] -+ adc r11, rax -+ -+ // [rcx+64], x3-x5 <- (AH+AL) x (BH+BL) - ALxBL -+ mov r12, [rcx+64] -+ mov r13, [rcx+72] -+ mov r14, [rcx+80] -+ mov r15, [rcx+88] -+ sub r12, [rcx] -+ sbb r13, [rcx+8] -+ sbb r14, [rcx+16] -+ sbb r15, [rcx+24] -+ sbb r8, [rcx+32] -+ sbb r9, [rcx+40] -+ sbb r10, [rcx+48] -+ sbb r11, [rcx+56] -+ -+ // r8-r15 <- (AH+AL) x (BH+BL) - ALxBL - AHxBH -+ sub r12, [rsp] -+ sbb r13, [rsp+8] -+ sbb r14, [rsp+16] -+ sbb r15, [rsp+24] -+ sbb r8, [rsp+32] -+ sbb r9, [rsp+40] -+ sbb r10, [rsp+48] -+ sbb r11, [rsp+56] -+ -+ add r12, [rcx+32] -+ mov [rcx+32], r12 // Result C4-C7 -+ adc r13, [rcx+40] -+ mov [rcx+40], r13 -+ adc r14, [rcx+48] -+ mov [rcx+48], r14 -+ adc r15, [rcx+56] -+ mov [rcx+56], r15 -+ mov rax, [rsp] -+ adc r8, rax -+ mov [rcx+64], r8 // Result C8-C15 -+ mov rax, [rsp+8] -+ adc r9, rax -+ mov [rcx+72], r9 -+ mov rax, [rsp+16] -+ adc r10, rax -+ mov [rcx+80], r10 -+ mov rax, [rsp+24] -+ adc r11, rax -+ mov [rcx+88], r11 -+ mov r12, [rsp+32] -+ adc r12, 0 -+ mov [rcx+96], r12 -+ mov r13, [rsp+40] -+ adc r13, 0 -+ mov [rcx+104], r13 -+ mov r14, [rsp+48] -+ adc r14, 0 -+ mov [rcx+112], r14 -+ mov r15, [rsp+56] -+ adc r15, 0 -+ mov [rcx+120], r15 -+ -+ add rsp, 96 -+ pop rbp -+ pop rbx -+ pop r15 -+ pop r14 -+ pop r13 -+ pop r12 -+ ret -+ -+//*********************************************************************** -+// Integer multiplication -+// Based on Karatsuba method -+// Operation: c [reg_p3] = a [reg_p1] * b [reg_p2] -+// NOTE: a=c or b=c are not allowed -+//*********************************************************************** -+.global mul503_asm -+mul503_asm: -+ mov ecx, [rip+OPENSSL_ia32cap_P+8] -+ and ecx, 0x80100 -+ cmp ecx, 0x80100 -+ je mul503_mulx_asm -+ -+ push r12 -+ push r13 -+ push r14 -+ mov rcx, reg_p3 -+ -+ // rcx[0-3] <- AH+AL -+ xor rax, rax -+ mov r8, [reg_p1+32] -+ mov r9, [reg_p1+40] -+ mov r10, [reg_p1+48] -+ mov r11, [reg_p1+56] -+ add r8, [reg_p1] -+ adc r9, [reg_p1+8] -+ adc r10, [reg_p1+16] -+ adc r11, [reg_p1+24] -+ push r15 -+ mov [rcx], r8 -+ mov [rcx+8], r9 -+ mov [rcx+16], r10 -+ mov [rcx+24], r11 -+ sbb rax, 0 -+ sub rsp, 80 // Allocating space in stack -+ -+ // r12-r15 <- BH+BL -+ xor rdx, rdx -+ mov r12, [reg_p2+32] -+ mov r13, [reg_p2+40] -+ mov r14, [reg_p2+48] -+ mov r15, [reg_p2+56] -+ add r12, [reg_p2] -+ adc r13, [reg_p2+8] -+ adc r14, [reg_p2+16] -+ adc r15, [reg_p2+24] -+ sbb rdx, 0 -+ mov [rsp+64], rax -+ mov [rsp+72], rdx -+ -+ // (rsp[0-3],r8,r9,r10,r11) <- (AH+AL)*(BH+BL) -+ mov rax, [rcx] -+ mul r12 -+ mov [rsp], rax // c0 -+ mov r8, rdx -+ -+ xor r9, r9 -+ mov rax, [rcx] -+ mul r13 -+ add r8, rax -+ adc r9, rdx -+ -+ xor r10, r10 -+ mov rax, [rcx+8] -+ mul r12 -+ add r8, rax -+ mov [rsp+8], r8 // c1 -+ adc r9, rdx -+ adc r10, 0 -+ -+ xor r8, r8 -+ mov rax, [rcx] -+ mul r14 -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ -+ mov rax, [rcx+16] -+ mul r12 -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ -+ mov rax, [rcx+8] -+ mul r13 -+ add r9, rax -+ mov [rsp+16], r9 // c2 -+ adc r10, rdx -+ adc r8, 0 -+ -+ xor r9, r9 -+ mov rax, [rcx] -+ mul r15 -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ -+ mov rax, [rcx+24] -+ mul r12 -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ -+ mov rax, [rcx+8] -+ mul r14 -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ -+ mov rax, [rcx+16] -+ mul r13 -+ add r10, rax -+ mov [rsp+24], r10 // c3 -+ adc r8, rdx -+ adc r9, 0 -+ -+ xor r10, r10 -+ mov rax, [rcx+8] -+ mul r15 -+ add r8, rax -+ adc r9, rdx -+ adc r10, 0 -+ -+ mov rax, [rcx+24] -+ mul r13 -+ add r8, rax -+ adc r9, rdx -+ adc r10, 0 -+ -+ mov rax, [rcx+16] -+ mul r14 -+ add r8, rax -+ mov [rsp+32], r8 // c4 -+ adc r9, rdx -+ adc r10, 0 -+ -+ xor r11, r11 -+ mov rax, [rcx+16] -+ mul r15 -+ add r9, rax -+ adc r10, rdx -+ adc r11, 0 -+ -+ mov rax, [rcx+24] -+ mul r14 -+ add r9, rax // c5 -+ adc r10, rdx -+ adc r11, 0 -+ -+ mov rax, [rcx+24] -+ mul r15 -+ add r10, rax // c6 -+ adc r11, rdx // c7 -+ -+ mov rax, [rsp+64] -+ and r12, rax -+ and r13, rax -+ and r14, rax -+ and r15, rax -+ add r12, r8 -+ adc r13, r9 -+ adc r14, r10 -+ adc r15, r11 -+ -+ mov rax, [rsp+72] -+ mov r8, [rcx] -+ mov r9, [rcx+8] -+ mov r10, [rcx+16] -+ mov r11, [rcx+24] -+ and r8, rax -+ and r9, rax -+ and r10, rax -+ and r11, rax -+ add r8, r12 -+ adc r9, r13 -+ adc r10, r14 -+ adc r11, r15 -+ mov [rsp+32], r8 -+ mov [rsp+40], r9 -+ mov [rsp+48], r10 -+ mov [rsp+56], r11 -+ -+ // rcx[0-7] <- AL*BL -+ mov r11, [reg_p1] -+ mov rax, [reg_p2] -+ mul r11 -+ xor r9, r9 -+ mov [rcx], rax // c0 -+ mov r8, rdx -+ -+ mov r14, [reg_p1+16] -+ mov rax, [reg_p2+8] -+ mul r11 -+ xor r10, r10 -+ add r8, rax -+ adc r9, rdx -+ -+ mov r12, [reg_p1+8] -+ mov rax, [reg_p2] -+ mul r12 -+ add r8, rax -+ mov [rcx+8], r8 // c1 -+ adc r9, rdx -+ adc r10, 0 -+ -+ xor r8, r8 -+ mov rax, [reg_p2+16] -+ mul r11 -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ -+ mov r13, [reg_p2] -+ mov rax, r14 -+ mul r13 -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ -+ mov rax, [reg_p2+8] -+ mul r12 -+ add r9, rax -+ mov [rcx+16], r9 // c2 -+ adc r10, rdx -+ adc r8, 0 -+ -+ xor r9, r9 -+ mov rax, [reg_p2+24] -+ mul r11 -+ mov r15, [reg_p1+24] -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ -+ mov rax, r15 -+ mul r13 -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ -+ mov rax, [reg_p2+16] -+ mul r12 -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ -+ mov rax, [reg_p2+8] -+ mul r14 -+ add r10, rax -+ mov [rcx+24], r10 // c3 -+ adc r8, rdx -+ adc r9, 0 -+ -+ xor r10, r10 -+ mov rax, [reg_p2+24] -+ mul r12 -+ add r8, rax -+ adc r9, rdx -+ adc r10, 0 -+ -+ mov rax, [reg_p2+8] -+ mul r15 -+ add r8, rax -+ adc r9, rdx -+ adc r10, 0 -+ -+ mov rax, [reg_p2+16] -+ mul r14 -+ add r8, rax -+ mov [rcx+32], r8 // c4 -+ adc r9, rdx -+ adc r10, 0 -+ -+ xor r8, r8 -+ mov rax, [reg_p2+24] -+ mul r14 -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ -+ mov rax, [reg_p2+16] -+ mul r15 -+ add r9, rax -+ mov [rcx+40], r9 // c5 -+ adc r10, rdx -+ adc r8, 0 -+ -+ mov rax, [reg_p2+24] -+ mul r15 -+ add r10, rax -+ mov [rcx+48], r10 // c6 -+ adc r8, rdx -+ mov [rcx+56], r8 // c7 -+ -+ // rcx[8-15] <- AH*BH -+ mov r11, [reg_p1+32] -+ mov rax, [reg_p2+32] -+ mul r11 -+ xor r9, r9 -+ mov [rcx+64], rax // c0 -+ mov r8, rdx -+ -+ mov r14, [reg_p1+48] -+ mov rax, [reg_p2+40] -+ mul r11 -+ xor r10, r10 -+ add r8, rax -+ adc r9, rdx -+ -+ mov r12, [reg_p1+40] -+ mov rax, [reg_p2+32] -+ mul r12 -+ add r8, rax -+ mov [rcx+72], r8 // c1 -+ adc r9, rdx -+ adc r10, 0 -+ -+ xor r8, r8 -+ mov rax, [reg_p2+48] -+ mul r11 -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ -+ mov r13, [reg_p2+32] -+ mov rax, r14 -+ mul r13 -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ -+ mov rax, [reg_p2+40] -+ mul r12 -+ add r9, rax -+ mov [rcx+80], r9 // c2 -+ adc r10, rdx -+ adc r8, 0 -+ -+ xor r9, r9 -+ mov rax, [reg_p2+56] -+ mul r11 -+ mov r15, [reg_p1+56] -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ -+ mov rax, r15 -+ mul r13 -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ -+ mov rax, [reg_p2+48] -+ mul r12 -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ -+ mov rax, [reg_p2+40] -+ mul r14 -+ add r10, rax -+ mov [rcx+88], r10 // c3 -+ adc r8, rdx -+ adc r9, 0 -+ -+ xor r10, r10 -+ mov rax, [reg_p2+56] -+ mul r12 -+ add r8, rax -+ adc r9, rdx -+ adc r10, 0 -+ -+ mov rax, [reg_p2+40] -+ mul r15 -+ add r8, rax -+ adc r9, rdx -+ adc r10, 0 -+ -+ mov rax, [reg_p2+48] -+ mul r14 -+ add r8, rax -+ mov [rcx+96], r8 // c4 -+ adc r9, rdx -+ adc r10, 0 -+ -+ xor r8, r8 -+ mov rax, [reg_p2+56] -+ mul r14 -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ -+ mov rax, [reg_p2+48] -+ mul r15 -+ add r9, rax -+ mov [rcx+104], r9 // c5 -+ adc r10, rdx -+ adc r8, 0 -+ -+ mov rax, [reg_p2+56] -+ mul r15 -+ add r10, rax -+ mov [rcx+112], r10 // c6 -+ adc r8, rdx -+ mov [rcx+120], r8 // c7 -+ -+ // [r8-r15] <- (AH+AL)*(BH+BL) - AL*BL -+ mov r8, [rsp] -+ sub r8, [rcx] -+ mov r9, [rsp+8] -+ sbb r9, [rcx+8] -+ mov r10, [rsp+16] -+ sbb r10, [rcx+16] -+ mov r11, [rsp+24] -+ sbb r11, [rcx+24] -+ mov r12, [rsp+32] -+ sbb r12, [rcx+32] -+ mov r13, [rsp+40] -+ sbb r13, [rcx+40] -+ mov r14, [rsp+48] -+ sbb r14, [rcx+48] -+ mov r15, [rsp+56] -+ sbb r15, [rcx+56] -+ -+ // [r8-r15] <- (AH+AL)*(BH+BL) - AL*BL - AH*BH -+ mov rax, [rcx+64] -+ sub r8, rax -+ mov rax, [rcx+72] -+ sbb r9, rax -+ mov rax, [rcx+80] -+ sbb r10, rax -+ mov rax, [rcx+88] -+ sbb r11, rax -+ mov rax, [rcx+96] -+ sbb r12, rax -+ mov rdx, [rcx+104] -+ sbb r13, rdx -+ mov rdi, [rcx+112] -+ sbb r14, rdi -+ mov rsi, [rcx+120] -+ sbb r15, rsi -+ -+ // Final result -+ add r8, [rcx+32] -+ mov [rcx+32], r8 -+ adc r9, [rcx+40] -+ mov [rcx+40], r9 -+ adc r10, [rcx+48] -+ mov [rcx+48], r10 -+ adc r11, [rcx+56] -+ mov [rcx+56], r11 -+ adc r12, [rcx+64] -+ mov [rcx+64], r12 -+ adc r13, [rcx+72] -+ mov [rcx+72], r13 -+ adc r14, [rcx+80] -+ mov [rcx+80], r14 -+ adc r15, [rcx+88] -+ mov [rcx+88], r15 -+ adc rax, 0 -+ mov [rcx+96], rax -+ adc rdx, 0 -+ mov [rcx+104], rdx -+ adc rdi, 0 -+ mov [rcx+112], rdi -+ adc rsi, 0 -+ mov [rcx+120], rsi -+ -+ add rsp, 80 // Restoring space in stack -+ pop r15 -+ pop r14 -+ pop r13 -+ pop r12 -+ ret -+ -+///////////////////////////////////////////////////////////////// MACRO -+// Schoolbook integer multiplication -+// Inputs: memory pointers M0 and M1 -+// Outputs: regs T0:T6 -+// Temps: regs T7:T9 -+///////////////////////////////////////////////////////////////// -+.macro MUL128x320_SCHOOL M0, M1, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 -+ mov rdx, \M0 -+ mulx \T1, \T0, \M1 // T0 <- C0_final -+ mulx \T2, \T4, 8\M1 -+ xor rax, rax -+ -+ mulx \T3, \T5, 16\M1 -+ adox \T1, \T4 -+ adox \T2, \T5 -+ mulx \T4, \T7, 24\M1 -+ adox \T3, \T7 -+ mulx \T5, \T6, 32\M1 -+ adox \T4, \T6 -+ adox \T5, rax -+ -+ mov rdx, 8\M0 -+ mulx \T7, \T6, \M1 -+ adcx \T1, \T6 // T1 <- C1_final -+ adcx \T2, \T7 -+ mulx \T6, \T8, 8\M1 -+ adcx \T3, \T6 -+ mulx \T9, \T7, 16\M1 -+ adcx \T4, \T9 -+ mulx \T6, \T9, 24\M1 -+ adcx \T5, \T6 -+ mulx \T6, rdx, 32\M1 -+ adcx \T6, rax -+ -+ xor rax, rax -+ adox \T2, \T8 -+ adox \T3, \T7 -+ adox \T4, \T9 -+ adox \T5, rdx -+ adox \T6, rax -+.endm -+ -+ -+//************************************************************************************** -+// Montgomery reduction -+// Based on method described in Faz-Hernandez et al. https://eprint.iacr.org/2017/1015 -+// Operation: c [reg_p2] = a [reg_p1] -+// NOTE: a=c is not allowed -+//************************************************************************************** -+rdc503_mulx_asm: -+ push rbx -+ push r12 -+ push r13 -+ push r14 -+ push r15 -+ -+ // a[0-1] x p503p1_nz --> result: r8:r14 -+ MUL128x320_SCHOOL [reg_p1], [rip+p503p1_nz], r8, r9, r10, r11, r12, r13, r14, rbx, rcx, r15 -+ -+ xor r15, r15 -+ add r8, [reg_p1+24] -+ adc r9, [reg_p1+32] -+ adc r10, [reg_p1+40] -+ adc r11, [reg_p1+48] -+ adc r12, [reg_p1+56] -+ adc r13, [reg_p1+64] -+ adc r14, [reg_p1+72] -+ adc r15, [reg_p1+80] -+ mov [reg_p1+24], r8 -+ mov [reg_p1+32], r9 -+ mov [reg_p1+40], r10 -+ mov [reg_p1+48], r11 -+ mov [reg_p1+56], r12 -+ mov [reg_p1+64], r13 -+ mov [reg_p1+72], r14 -+ mov [reg_p1+80], r15 -+ mov r8, [reg_p1+88] -+ mov r9, [reg_p1+96] -+ mov r10, [reg_p1+104] -+ mov r11, [reg_p1+112] -+ mov r12, [reg_p1+120] -+ adc r8, 0 -+ adc r9, 0 -+ adc r10, 0 -+ adc r11, 0 -+ adc r12, 0 -+ mov [reg_p1+88], r8 -+ mov [reg_p1+96], r9 -+ mov [reg_p1+104], r10 -+ mov [reg_p1+112], r11 -+ mov [reg_p1+120], r12 -+ -+ // a[2-3] x p503p1_nz --> result: r8:r14 -+ MUL128x320_SCHOOL [reg_p1+16], [rip+p503p1_nz], r8, r9, r10, r11, r12, r13, r14, rbx, rcx, r15 -+ -+ xor r15, r15 -+ add r8, [reg_p1+40] -+ adc r9, [reg_p1+48] -+ adc r10, [reg_p1+56] -+ adc r11, [reg_p1+64] -+ adc r12, [reg_p1+72] -+ adc r13, [reg_p1+80] -+ adc r14, [reg_p1+88] -+ adc r15, [reg_p1+96] -+ mov [reg_p1+40], r8 -+ mov [reg_p1+48], r9 -+ mov [reg_p1+56], r10 -+ mov [reg_p1+64], r11 -+ mov [reg_p1+72], r12 -+ mov [reg_p1+80], r13 -+ mov [reg_p1+88], r14 -+ mov [reg_p1+96], r15 -+ mov r8, [reg_p1+104] -+ mov r9, [reg_p1+112] -+ mov r10, [reg_p1+120] -+ adc r8, 0 -+ adc r9, 0 -+ adc r10, 0 -+ mov [reg_p1+104], r8 -+ mov [reg_p1+112], r9 -+ mov [reg_p1+120], r10 -+ -+ // a[4-5] x p503p1_nz --> result: r8:r14 -+ MUL128x320_SCHOOL [reg_p1+32], [rip+p503p1_nz], r8, r9, r10, r11, r12, r13, r14, rbx, rcx, r15 -+ -+ xor r15, r15 -+ xor rbx, rbx -+ add r8, [reg_p1+56] -+ adc r9, [reg_p1+64] -+ adc r10, [reg_p1+72] -+ adc r11, [reg_p1+80] -+ adc r12, [reg_p1+88] -+ adc r13, [reg_p1+96] -+ adc r14, [reg_p1+104] -+ adc r15, [reg_p1+112] -+ adc rbx, [reg_p1+120] -+ mov [reg_p1+56], r8 -+ mov [reg_p2], r9 // Final result c0 -+ mov [reg_p1+72], r10 -+ mov [reg_p1+80], r11 -+ mov [reg_p1+88], r12 -+ mov [reg_p1+96], r13 -+ mov [reg_p1+104], r14 -+ mov [reg_p1+112], r15 -+ mov [reg_p1+120], rbx -+ -+ // a[6-7] x p503p1_nz --> result: r8:r14 -+ MUL128x320_SCHOOL [reg_p1+48], [rip+p503p1_nz], r8, r9, r10, r11, r12, r13, r14, rbx, rcx, r15 -+ -+ // Final result c1:c7 -+ add r8, [reg_p1+72] -+ adc r9, [reg_p1+80] -+ adc r10, [reg_p1+88] -+ adc r11, [reg_p1+96] -+ adc r12, [reg_p1+104] -+ adc r13, [reg_p1+112] -+ adc r14, [reg_p1+120] -+ mov [reg_p2+8], r8 -+ mov [reg_p2+16], r9 -+ mov [reg_p2+24], r10 -+ mov [reg_p2+32], r11 -+ mov [reg_p2+40], r12 -+ mov [reg_p2+48], r13 -+ mov [reg_p2+56], r14 -+ -+ pop r15 -+ pop r14 -+ pop r13 -+ pop r12 -+ pop rbx -+ ret -+ -+//*********************************************************************** -+// Montgomery reduction -+// Based on comba method -+// Operation: c [reg_p2] = a [reg_p1] -+// NOTE: a=c is not allowed -+//*********************************************************************** -+.global rdc503_asm -+rdc503_asm: -+ mov ecx, [rip+OPENSSL_ia32cap_P+8] -+ and ecx, 0x80100 -+ cmp ecx, 0x80100 -+ je rdc503_mulx_asm -+ -+ push r12 -+ push r13 -+ push r14 -+ push r15 -+ -+ mov r11, [reg_p1] -+ mov rax, p503p1_3 -+ mul r11 -+ xor r8, r8 -+ add rax, [reg_p1+24] -+ mov [reg_p2+24], rax // z3 -+ adc r8, rdx -+ -+ xor r9, r9 -+ mov rax, p503p1_4 -+ mul r11 -+ xor r10, r10 -+ add r8, rax -+ adc r9, rdx -+ -+ mov r12, [reg_p1+8] -+ mov rax, p503p1_3 -+ mul r12 -+ add r8, rax -+ adc r9, rdx -+ adc r10, 0 -+ add r8, [reg_p1+32] -+ mov [reg_p2+32], r8 // z4 -+ adc r9, 0 -+ adc r10, 0 -+ -+ xor r8, r8 -+ mov rax, p503p1_5 -+ mul r11 -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ -+ mov rax, p503p1_4 -+ mul r12 -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ -+ mov r13, [reg_p1+16] -+ mov rax, p503p1_3 -+ mul r13 -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ add r9, [reg_p1+40] -+ mov [reg_p2+40], r9 // z5 -+ adc r10, 0 -+ adc r8, 0 -+ -+ xor r9, r9 -+ mov rax, p503p1_6 -+ mul r11 -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ -+ mov rax, p503p1_5 -+ mul r12 -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ -+ mov rax, p503p1_4 -+ mul r13 -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ -+ mov r14, [reg_p2+24] -+ mov rax, p503p1_3 -+ mul r14 -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ add r10, [reg_p1+48] -+ mov [reg_p2+48], r10 // z6 -+ adc r8, 0 -+ adc r9, 0 -+ -+ xor r10, r10 -+ mov rax, p503p1_7 -+ mul r11 -+ add r8, rax -+ adc r9, rdx -+ adc r10, 0 -+ -+ mov rax, p503p1_6 -+ mul r12 -+ add r8, rax -+ adc r9, rdx -+ adc r10, 0 -+ -+ mov rax, p503p1_5 -+ mul r13 -+ add r8, rax -+ adc r9, rdx -+ adc r10, 0 -+ -+ mov rax, p503p1_4 -+ mul r14 -+ add r8, rax -+ adc r9, rdx -+ adc r10, 0 -+ -+ mov r15, [reg_p2+32] -+ mov rax, p503p1_3 -+ mul r15 -+ add r8, rax -+ adc r9, rdx -+ adc r10, 0 -+ add r8, [reg_p1+56] -+ mov [reg_p2+56], r8 // z7 -+ adc r9, 0 -+ adc r10, 0 -+ -+ xor r8, r8 -+ mov rax, p503p1_7 -+ mul r12 -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ -+ mov rax, p503p1_6 -+ mul r13 -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ -+ mov rax, p503p1_5 -+ mul r14 -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ -+ mov rax, p503p1_4 -+ mul r15 -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ -+ mov rcx, [reg_p2+40] -+ mov rax, p503p1_3 -+ mul rcx -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ add r9, [reg_p1+64] -+ mov [reg_p2], r9 // z0 -+ adc r10, 0 -+ adc r8, 0 -+ -+ xor r9, r9 -+ mov rax, p503p1_7 -+ mul r13 -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ -+ mov rax, p503p1_6 -+ mul r14 -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ -+ mov rax, p503p1_5 -+ mul r15 -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ -+ mov rax, p503p1_4 -+ mul rcx -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ -+ mov r13, [reg_p2+48] -+ mov rax, p503p1_3 -+ mul r13 -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ add r10, [reg_p1+72] -+ mov [reg_p2+8], r10 // z1 -+ adc r8, 0 -+ adc r9, 0 -+ -+ xor r10, r10 -+ mov rax, p503p1_7 -+ mul r14 -+ add r8, rax -+ adc r9, rdx -+ adc r10, 0 -+ -+ mov rax, p503p1_6 -+ mul r15 -+ add r8, rax -+ adc r9, rdx -+ adc r10, 0 -+ -+ mov rax, p503p1_5 -+ mul rcx -+ add r8, rax -+ adc r9, rdx -+ adc r10, 0 -+ -+ mov rax, p503p1_4 -+ mul r13 -+ add r8, rax -+ adc r9, rdx -+ adc r10, 0 -+ -+ mov r14, [reg_p2+56] -+ mov rax, p503p1_3 -+ mul r14 -+ add r8, rax -+ adc r9, rdx -+ adc r10, 0 -+ add r8, [reg_p1+80] -+ mov [reg_p2+16], r8 // z2 -+ adc r9, 0 -+ adc r10, 0 -+ -+ xor r8, r8 -+ mov rax, p503p1_7 -+ mul r15 -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ -+ mov rax, p503p1_6 -+ mul rcx -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ -+ mov rax, p503p1_5 -+ mul r13 -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ -+ mov rax, p503p1_4 -+ mul r14 -+ add r9, rax -+ adc r10, rdx -+ adc r8, 0 -+ add r9, [reg_p1+88] -+ mov [reg_p2+24], r9 // z3 -+ adc r10, 0 -+ adc r8, 0 -+ -+ xor r9, r9 -+ mov rax, p503p1_7 -+ mul rcx -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ -+ mov rax, p503p1_6 -+ mul r13 -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ -+ mov rax, p503p1_5 -+ mul r14 -+ add r10, rax -+ adc r8, rdx -+ adc r9, 0 -+ add r10, [reg_p1+96] -+ mov [reg_p2+32], r10 // z4 -+ adc r8, 0 -+ adc r9, 0 -+ -+ xor r10, r10 -+ mov rax, p503p1_7 -+ mul r13 -+ add r8, rax -+ adc r9, rdx -+ adc r10, 0 -+ -+ mov rax, p503p1_6 -+ mul r14 -+ add r8, rax -+ adc r9, rdx -+ adc r10, 0 -+ add r8, [reg_p1+104] // z5 -+ mov [reg_p2+40], r8 // z5 -+ adc r9, 0 -+ adc r10, 0 -+ -+ mov rax, p503p1_7 -+ mul r14 -+ add r9, rax -+ adc r10, rdx -+ add r9, [reg_p1+112] // z6 -+ mov [reg_p2+48], r9 // z6 -+ adc r10, 0 -+ add r10, [reg_p1+120] // z7 -+ mov [reg_p2+56], r10 // z7 -+ -+ pop r15 -+ pop r14 -+ pop r13 -+ pop r12 -+ ret -+ -+//*********************************************************************** -+// 503-bit multiprecision addition -+// Operation: c [reg_p3] = a [reg_p1] + b [reg_p2] -+//*********************************************************************** -+.global mp_add503_asm -+mp_add503_asm: -+ mov r8, [reg_p1] -+ mov r9, [reg_p1+8] -+ mov r10, [reg_p1+16] -+ mov r11, [reg_p1+24] -+ add r8, [reg_p2] -+ adc r9, [reg_p2+8] -+ adc r10, [reg_p2+16] -+ adc r11, [reg_p2+24] -+ mov [reg_p3], r8 -+ mov [reg_p3+8], r9 -+ mov [reg_p3+16], r10 -+ mov [reg_p3+24], r11 -+ -+ mov r8, [reg_p1+32] -+ mov r9, [reg_p1+40] -+ mov r10, [reg_p1+48] -+ mov r11, [reg_p1+56] -+ adc r8, [reg_p2+32] -+ adc r9, [reg_p2+40] -+ adc r10, [reg_p2+48] -+ adc r11, [reg_p2+56] -+ mov [reg_p3+32], r8 -+ mov [reg_p3+40], r9 -+ mov [reg_p3+48], r10 -+ mov [reg_p3+56], r11 -+ ret -+ -+ -+//*********************************************************************** -+// 2x503-bit multiprecision subtraction -+// Operation: c [reg_p3] = a [reg_p1] - b [reg_p2]. Returns borrow mask -+//*********************************************************************** -+.global mp_sub503x2_asm -+mp_sub503x2_asm: -+ xor rax, rax -+ mov r8, [reg_p1] -+ mov r9, [reg_p1+8] -+ mov r10, [reg_p1+16] -+ mov r11, [reg_p1+24] -+ mov rcx, [reg_p1+32] -+ sub r8, [reg_p2] -+ sbb r9, [reg_p2+8] -+ sbb r10, [reg_p2+16] -+ sbb r11, [reg_p2+24] -+ sbb rcx, [reg_p2+32] -+ mov [reg_p3], r8 -+ mov [reg_p3+8], r9 -+ mov [reg_p3+16], r10 -+ mov [reg_p3+24], r11 -+ mov [reg_p3+32], rcx -+ -+ mov r8, [reg_p1+40] -+ mov r9, [reg_p1+48] -+ mov r10, [reg_p1+56] -+ mov r11, [reg_p1+64] -+ mov rcx, [reg_p1+72] -+ sbb r8, [reg_p2+40] -+ sbb r9, [reg_p2+48] -+ sbb r10, [reg_p2+56] -+ sbb r11, [reg_p2+64] -+ sbb rcx, [reg_p2+72] -+ mov [reg_p3+40], r8 -+ mov [reg_p3+48], r9 -+ mov [reg_p3+56], r10 -+ mov [reg_p3+64], r11 -+ mov [reg_p3+72], rcx -+ -+ mov r8, [reg_p1+80] -+ mov r9, [reg_p1+88] -+ mov r10, [reg_p1+96] -+ mov r11, [reg_p1+104] -+ mov rcx, [reg_p1+112] -+ sbb r8, [reg_p2+80] -+ sbb r9, [reg_p2+88] -+ sbb r10, [reg_p2+96] -+ sbb r11, [reg_p2+104] -+ sbb rcx, [reg_p2+112] -+ mov [reg_p3+80], r8 -+ mov [reg_p3+88], r9 -+ mov [reg_p3+96], r10 -+ mov [reg_p3+104], r11 -+ mov [reg_p3+112], rcx -+ -+ mov r8, [reg_p1+120] -+ sbb r8, [reg_p2+120] -+ sbb rax, 0 -+ mov [reg_p3+120], r8 -+ ret -+ -+ -+//*********************************************************************** -+// Double 2x503-bit multiprecision subtraction -+// Operation: c [reg_p3] = c [reg_p3] - a [reg_p1] - b [reg_p2] -+//*********************************************************************** -+.global mp_dblsub503x2_asm -+mp_dblsub503x2_asm: -+ push r12 -+ push r13 -+ push r14 -+ -+ xor rax, rax -+ mov r8, [reg_p3] -+ mov r9, [reg_p3+8] -+ mov r10, [reg_p3+16] -+ mov r11, [reg_p3+24] -+ mov r12, [reg_p3+32] -+ mov r13, [reg_p3+40] -+ mov r14, [reg_p3+48] -+ mov rcx, [reg_p3+56] -+ sub r8, [reg_p1] -+ sbb r9, [reg_p1+8] -+ sbb r10, [reg_p1+16] -+ sbb r11, [reg_p1+24] -+ sbb r12, [reg_p1+32] -+ sbb r13, [reg_p1+40] -+ sbb r14, [reg_p1+48] -+ sbb rcx, [reg_p1+56] -+ adc rax, 0 -+ sub r8, [reg_p2] -+ sbb r9, [reg_p2+8] -+ sbb r10, [reg_p2+16] -+ sbb r11, [reg_p2+24] -+ sbb r12, [reg_p2+32] -+ sbb r13, [reg_p2+40] -+ sbb r14, [reg_p2+48] -+ sbb rcx, [reg_p2+56] -+ adc rax, 0 -+ mov [reg_p3], r8 -+ mov [reg_p3+8], r9 -+ mov [reg_p3+16], r10 -+ mov [reg_p3+24], r11 -+ mov [reg_p3+32], r12 -+ mov [reg_p3+40], r13 -+ mov [reg_p3+48], r14 -+ mov [reg_p3+56], rcx -+ -+ mov r8, [reg_p3+64] -+ mov r9, [reg_p3+72] -+ mov r10, [reg_p3+80] -+ mov r11, [reg_p3+88] -+ mov r12, [reg_p3+96] -+ mov r13, [reg_p3+104] -+ mov r14, [reg_p3+112] -+ mov rcx, [reg_p3+120] -+ sub r8, rax -+ sbb r8, [reg_p1+64] -+ sbb r9, [reg_p1+72] -+ sbb r10, [reg_p1+80] -+ sbb r11, [reg_p1+88] -+ sbb r12, [reg_p1+96] -+ sbb r13, [reg_p1+104] -+ sbb r14, [reg_p1+112] -+ sbb rcx, [reg_p1+120] -+ sub r8, [reg_p2+64] -+ sbb r9, [reg_p2+72] -+ sbb r10, [reg_p2+80] -+ sbb r11, [reg_p2+88] -+ sbb r12, [reg_p2+96] -+ sbb r13, [reg_p2+104] -+ sbb r14, [reg_p2+112] -+ sbb rcx, [reg_p2+120] -+ mov [reg_p3+64], r8 -+ mov [reg_p3+72], r9 -+ mov [reg_p3+80], r10 -+ mov [reg_p3+88], r11 -+ mov [reg_p3+96], r12 -+ mov [reg_p3+104], r13 -+ mov [reg_p3+112], r14 -+ mov [reg_p3+120], rcx -+ -+ pop r14 -+ pop r13 -+ pop r12 -+ ret -diff --git a/third_party/sidh/src/ARM64/fp_arm64.c b/third_party/sidh/src/ARM64/fp_arm64.c -new file mode 100644 -index 000000000..3a99cfc19 ---- /dev/null -+++ b/third_party/sidh/src/ARM64/fp_arm64.c -@@ -0,0 +1,92 @@ -+/******************************************************************************************** -+* SIDH: an efficient supersingular isogeny cryptography library -+* -+* Abstract: modular arithmetic optimized for 64-bit ARMv8 platforms for P503 -+*********************************************************************************************/ -+ -+#include "../internal.h" -+#include "../P503_internal.h" -+ -+// Global constants -+extern const struct params_t kP503Params; -+ -+inline void fpadd503(const digit_t* a, const digit_t* b, digit_t* c) -+{ // Modular addition, c = a+b mod p503. -+ // Inputs: a, b in [0, 2*p503-1] -+ // Output: c in [0, 2*p503-1] -+ -+ fpadd503_asm(a, b, c); -+} -+ -+ -+inline void fpsub503(const digit_t* a, const digit_t* b, digit_t* c) -+{ // Modular subtraction, c = a-b mod p503. -+ // Inputs: a, b in [0, 2*p503-1] -+ // Output: c in [0, 2*p503-1] -+ -+ fpsub503_asm(a, b, c); -+} -+ -+ -+inline void fpneg503(digit_t* a) -+{ // Modular negation, a = -a mod p503. -+ // Input/output: a in [0, 2*p503-1] -+ unsigned int i, borrow = 0; -+ -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ SUBC(borrow, ((digit_t*)kP503Params.primeX2)[i], a[i], borrow, a[i]); -+ } -+} -+ -+ -+void fpdiv2_503(const digit_t* a, digit_t* c) -+{ // Modular division by two, c = a/2 mod p503. -+ // Input : a in [0, 2*p503-1] -+ // Output: c in [0, 2*p503-1] -+ unsigned int i, carry = 0; -+ digit_t mask; -+ -+ mask = 0 - (digit_t)(a[0] & 1); // If a is odd compute a+p521 -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ ADDC(carry, a[i], ((digit_t*)kP503Params.prime)[i] & mask, carry, c[i]); -+ } -+ -+ mp_shiftr1(c, NWORDS_FIELD); -+} -+ -+ -+void fpcorrection503(digit_t* a) -+{ // Modular correction to reduce field element a in [0, 2*p503-1] to [0, p503-1]. -+ unsigned int i, borrow = 0; -+ digit_t mask; -+ -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ SUBC(borrow, a[i], ((digit_t*)kP503Params.prime)[i], borrow, a[i]); -+ } -+ mask = 0 - (digit_t)borrow; -+ -+ borrow = 0; -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ ADDC(borrow, a[i], ((digit_t*)kP503Params.prime)[i] & mask, borrow, a[i]); -+ } -+} -+ -+ -+void mp_mul(const digit_t* a, const digit_t* b, digit_t* c, const unsigned int nwords) -+{ // Multiprecision multiply, c = a*b, where lng(a) = lng(b) = nwords. -+ -+ UNREFERENCED_PARAMETER(nwords); -+ -+ mul503_asm(a, b, c); -+} -+ -+ -+ -+void rdc_mont(const digit_t* ma, digit_t* mc) -+{ // Montgomery reduction exploiting special form of the prime. -+ // mc = ma*R^-1 mod p503x2, where R = 2^512. -+ // If ma < 2^512*p503, the output mc is in the range [0, 2*p503-1]. -+ // ma is assumed to be in Montgomery representation. -+ -+ rdc503_asm(ma, mc); -+} -diff --git a/third_party/sidh/src/ARM64/fp_arm64_asm.S b/third_party/sidh/src/ARM64/fp_arm64_asm.S -new file mode 100644 -index 000000000..7f96452c2 ---- /dev/null -+++ b/third_party/sidh/src/ARM64/fp_arm64_asm.S -@@ -0,0 +1,826 @@ -+//******************************************************************************************* -+// SIDH: an efficient supersingular isogeny cryptography library -+// -+// Abstract: field arithmetic in 64-bit ARMv8 assembly for P503 on Linux -+//******************************************************************************************* -+ -+// p503 + 1 -+p503p1: -+#define P503P1_0 0xAC00000000000000 -+#define P503P1_1 0x13085BDA2211E7A0 -+#define P503P1_2 0x1B9BF6C87B7E7DAF -+#define P503P1_3 0x6045C6BDDA77A4D0 -+#define P503P1_4 0x004066F541811E1E -+ -+// 2 * p503 -+p503x2: -+#define P503x2_0 0xFFFFFFFFFFFFFFFE -+#define P503x2_1 0xFFFFFFFFFFFFFFFF -+#define P503x2_2 0x57FFFFFFFFFFFFFF -+#define P503x2_3 0x2610B7B44423CF41 -+#define P503x2_4 0x3737ED90F6FCFB5E -+#define P503x2_5 0xC08B8D7BB4EF49A0 -+#define P503x2_6 0x0080CDEA83023C3C -+ -+#define P503P1_NZ_S8_0 0x85BDA2211E7A0AC -+#define P503P1_NZ_S8_1 0x9BF6C87B7E7DAF13 -+#define P503P1_NZ_S8_2 0x45C6BDDA77A4D01B -+#define P503P1_NZ_S8_3 0x4066F541811E1E60 -+ -+ -+.text -+//*********************************************************************** -+// Field addition -+// Operation: c [x2] = a [x0] + b [x1] -+//*********************************************************************** -+.global fpadd503_asm -+fpadd503_asm: -+ ldp x3, x4, [x0,#0] -+ ldp x5, x6, [x0,#16] -+ ldp x11, x12, [x1,#0] -+ ldp x13, x14, [x1,#16] -+ -+ // Add a + b -+ adds x3, x3, x11 -+ adcs x4, x4, x12 -+ adcs x5, x5, x13 -+ adcs x6, x6, x14 -+ ldp x7, x8, [x0,#32] -+ ldp x9, x10, [x0,#48] -+ ldp x15, x16, [x1,#32] -+ ldp x17, x18, [x1,#48] -+ adcs x7, x7, x15 -+ adcs x8, x8, x16 -+ adcs x9, x9, x17 -+ adc x10, x10, x18 -+ -+ // Subtract 2xp503 -+ ldr x11, =P503x2_0 -+ ldr x12, =P503x2_1 -+ ldr x13, =P503x2_2 -+ ldr x14, =P503x2_3 -+ subs x3, x3, x11 -+ sbcs x4, x4, x12 -+ sbcs x5, x5, x12 -+ sbcs x6, x6, x13 -+ sbcs x7, x7, x14 -+ ldr x15, =P503x2_4 -+ ldr x16, =P503x2_5 -+ ldr x17, =P503x2_6 -+ sbcs x8, x8, x15 -+ sbcs x9, x9, x16 -+ sbcs x10, x10, x17 -+ sbc x18, xzr, xzr -+ -+ // Add 2xp503 anded with the mask in x18 -+ and x11, x11, x18 -+ and x12, x12, x18 -+ and x13, x13, x18 -+ and x14, x14, x18 -+ and x15, x15, x18 -+ and x16, x16, x18 -+ and x17, x17, x18 -+ -+ adds x3, x3, x11 -+ adcs x4, x4, x12 -+ adcs x5, x5, x12 -+ adcs x6, x6, x13 -+ adcs x7, x7, x14 -+ adcs x8, x8, x15 -+ adcs x9, x9, x16 -+ adc x10, x10, x17 -+ -+ stp x3, x4, [x2,#0] -+ stp x5, x6, [x2,#16] -+ stp x7, x8, [x2,#32] -+ stp x9, x10, [x2,#48] -+ ret -+ -+ -+//*********************************************************************** -+// Field subtraction -+// Operation: c [x2] = a [x0] - b [x1] -+//*********************************************************************** -+.global fpsub503_asm -+fpsub503_asm: -+ ldp x3, x4, [x0,#0] -+ ldp x5, x6, [x0,#16] -+ ldp x11, x12, [x1,#0] -+ ldp x13, x14, [x1,#16] -+ -+ // Subtract a - b -+ subs x3, x3, x11 -+ sbcs x4, x4, x12 -+ sbcs x5, x5, x13 -+ sbcs x6, x6, x14 -+ ldp x7, x8, [x0,#32] -+ ldp x9, x10, [x0,#48] -+ ldp x15, x16, [x1,#32] -+ ldp x17, x18, [x1,#48] -+ sbcs x7, x7, x15 -+ sbcs x8, x8, x16 -+ sbcs x9, x9, x17 -+ sbcs x10, x10, x18 -+ sbc x18, xzr, xzr -+ -+ // Add 2xp503 anded with the mask in x18 -+ ldr x11, =P503x2_0 -+ ldr x12, =P503x2_1 -+ ldr x13, =P503x2_2 -+ ldr x14, =P503x2_3 -+ and x11, x11, x18 -+ and x12, x12, x18 -+ and x13, x13, x18 -+ and x14, x14, x18 -+ ldr x15, =P503x2_4 -+ ldr x16, =P503x2_5 -+ ldr x17, =P503x2_6 -+ and x15, x15, x18 -+ and x16, x16, x18 -+ and x17, x17, x18 -+ -+ adds x3, x3, x11 -+ adcs x4, x4, x12 -+ adcs x5, x5, x12 -+ adcs x6, x6, x13 -+ adcs x7, x7, x14 -+ adcs x8, x8, x15 -+ adcs x9, x9, x16 -+ adc x10, x10, x17 -+ -+ stp x3, x4, [x2,#0] -+ stp x5, x6, [x2,#16] -+ stp x7, x8, [x2,#32] -+ stp x9, x10, [x2,#48] -+ ret -+ -+ -+//////////////////////////////////////////// MACRO -+.macro MUL128_COMBA_CUT A0, A1, B0, B1, C0, C1, C2, C3, T0 -+ mul \A0, \A1, \B0 -+ umulh \B0, \A1, \B0 -+ adds \C1, \C1, \C3 -+ adc \C2, \C2, xzr -+ -+ mul \T0, \A1, \B1 -+ umulh \B1, \A1, \B1 -+ adds \C1, \C1, \A0 -+ adcs \C2, \C2, \B0 -+ adc \C3, xzr, xzr -+ -+ adds \C2, \C2, \T0 -+ adc \C3, \C3, \B1 -+.endm -+ -+ -+//////////////////////////////////////////// MACRO -+.macro MUL256_KARATSUBA_COMBA M,A0,A1,A2,A3,B0,B1,B2,B3,C0,C1,C2,C3,C4,C5,C6,C7,T0,T1 -+ -+ // A0-A1 <- AH + AL, T0 <- mask -+ adds \A0, \A0, \A2 -+ adcs \A1, \A1, \A3 -+ adc \T0, xzr, xzr -+ -+ // C6, T1 <- BH + BL, C7 <- mask -+ adds \C6, \B0, \B2 -+ adcs \T1, \B1, \B3 -+ adc \C7, xzr, xzr -+ -+ // C0-C1 <- masked (BH + BL) -+ sub \C2, xzr, \T0 -+ sub \C3, xzr, \C7 -+ and \C0, \C6, \C2 -+ and \C1, \T1, \C2 -+ -+ // C4-C5 <- masked (AH + AL), T0 <- combined carry -+ and \C4, \A0, \C3 -+ and \C5, \A1, \C3 -+ mul \C2, \A0, \C6 -+ mul \C3, \A0, \T1 -+ and \T0, \T0, \C7 -+ -+ // C0-C1, T0 <- (AH+AL) x (BH+BL), part 1 -+ adds \C0, \C4, \C0 -+ umulh \C4, \A0, \T1 -+ adcs \C1, \C5, \C1 -+ umulh \C5, \A0, \C6 -+ adc \T0, \T0, xzr -+ -+ // C2-C5 <- (AH+AL) x (BH+BL), low part -+ MUL128_COMBA_CUT \A0, \A1, \C6, \T1, \C2, \C3, \C4, \C5, \C7 -+ ldp \A0, \A1, [\M,#0] -+ -+ // C2-C5, T0 <- (AH+AL) x (BH+BL), final part -+ adds \C4, \C0, \C4 -+ umulh \C7, \A0, \B0 -+ umulh \T1, \A0, \B1 -+ adcs \C5, \C1, \C5 -+ mul \C0, \A0, \B0 -+ mul \C1, \A0, \B1 -+ adc \T0, \T0, xzr -+ -+ // C0-C1, T1, C7 <- AL x BL -+ MUL128_COMBA_CUT \A0, \A1, \B0, \B1, \C0, \C1, \T1, \C7, \C6 -+ -+ // C2-C5, T0 <- (AH+AL) x (BH+BL) - ALxBL -+ mul \A0, \A2, \B2 -+ umulh \B0, \A2, \B2 -+ subs \C2, \C2, \C0 -+ sbcs \C3, \C3, \C1 -+ sbcs \C4, \C4, \T1 -+ mul \A1, \A2, \B3 -+ umulh \C6, \A2, \B3 -+ sbcs \C5, \C5, \C7 -+ sbc \T0, \T0, xzr -+ -+ // A0, A1, C6, B0 <- AH x BH -+ MUL128_COMBA_CUT \A2, \A3, \B2, \B3, \A0, \A1, \C6, \B0, \B1 -+ -+ // C2-C5, T0 <- (AH+AL) x (BH+BL) - ALxBL - AHxBH -+ subs \C2, \C2, \A0 -+ sbcs \C3, \C3, \A1 -+ sbcs \C4, \C4, \C6 -+ sbcs \C5, \C5, \B0 -+ sbc \T0, \T0, xzr -+ -+ adds \C2, \C2, \T1 -+ adcs \C3, \C3, \C7 -+ adcs \C4, \C4, \A0 -+ adcs \C5, \C5, \A1 -+ adcs \C6, \T0, \C6 -+ adc \C7, \B0, xzr -+.endm -+ -+ -+//*********************************************************************************** -+// 512-bit integer multiplication using Karatsuba (two levels), Comba (lower level) -+// Operation: c [x2] = a [x0] * b [x1] -+//*********************************************************************************** -+.global mul503_asm -+mul503_asm: -+ sub sp, sp, #96 -+ stp x19, x20, [sp,#0] -+ stp x21, x22, [sp,#16] -+ stp x23, x24, [sp,#32] -+ stp x25, x26, [sp,#48] -+ stp x27, x28, [sp,#64] -+ str x29, [sp, #80] -+ -+ ldp x3, x4, [x0] -+ ldp x5, x6, [x0,#16] -+ ldp x7, x8, [x0,#32] -+ ldp x9, x10, [x0,#48] -+ ldp x11, x12, [x1,#0] -+ ldp x13, x14, [x1,#16] -+ ldp x15, x16, [x1,#32] -+ ldp x17, x18, [x1,#48] -+ -+ // x26-x29 <- AH + AL, x7 <- mask -+ adds x26, x3, x7 -+ adcs x27, x4, x8 -+ adcs x28, x5, x9 -+ adcs x29, x6, x10 -+ adc x7, xzr, xzr -+ -+ // x11-x14 <- BH + BL, x8 <- mask -+ adds x11, x11, x15 -+ adcs x12, x12, x16 -+ adcs x13, x13, x17 -+ adcs x14, x14, x18 -+ adc x8, xzr, xzr -+ -+ // x15-x18 <- masked (BH + BL) -+ sub x9, xzr, x7 -+ sub x10, xzr, x8 -+ and x15, x11, x9 -+ and x16, x12, x9 -+ and x17, x13, x9 -+ and x18, x14, x9 -+ -+ // x19-x22 <- masked (AH + AL), x7 <- combined carry -+ and x19, x26, x10 -+ and x20, x27, x10 -+ and x21, x28, x10 -+ and x22, x29, x10 -+ and x7, x7, x8 -+ -+ // x15-x18, x7 <- masked (AH+AL) + masked (BH+BL), step 1 -+ adds x15, x15, x19 -+ adcs x16, x16, x20 -+ adcs x17, x17, x21 -+ adcs x18, x18, x22 -+ adc x7, x7, xzr -+ -+ // x8-x10,x19-x23 <- (AH+AL) x (BH+BL), low part -+ stp x26, x27, [x2,#0] -+ MUL256_KARATSUBA_COMBA x2, x26, x27, x28, x29, x11, x12, x13, x14, x8, x9, x10, x19, x20, x21, x22, x23, x24, x25 -+ -+ // x15-x18, x7 <- (AH+AL) x (BH+BL), final step -+ adds x15, x15, x20 -+ adcs x16, x16, x21 -+ adcs x17, x17, x22 -+ adcs x18, x18, x23 -+ adc x7, x7, xzr -+ -+ // x20-x27 <- AL x BL -+ ldp x11, x12, [x1,#0] -+ ldp x13, x14, [x1,#16] -+ MUL256_KARATSUBA_COMBA x0, x3, x4, x5, x6, x11, x12, x13, x14, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29 -+ -+ // x13-x14, x3-x5 <- (AH+AL) x (BH+BL) - ALxBL -+ subs x8, x8, x20 -+ sbcs x9, x9, x21 -+ sbcs x10, x10, x22 -+ sbcs x19, x19, x23 -+ sbcs x15, x15, x24 -+ sbcs x16, x16, x25 -+ sbcs x17, x17, x26 -+ sbcs x18, x18, x27 -+ sbc x7, x7, xzr -+ -+ stp x20, x21, [x2] -+ stp x22, x23, [x2,#16] -+ -+ ldp x3, x4, [x0,#32] -+ ldp x5, x6, [x0,#48] -+ ldp x11, x12, [x1,#32] -+ ldp x13, x14, [x1,#48] -+ -+ adds x8, x8, x24 -+ adcs x9, x9, x25 -+ adcs x10, x10, x26 -+ adcs x19, x19, x27 -+ adc x1, xzr, xzr -+ -+ // x20-x27 <- AH x BH -+ add x0, x0, #32 -+ MUL256_KARATSUBA_COMBA x0, x3, x4, x5, x6, x11, x12, x13, x14, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29 -+ neg x1, x1 -+ -+ // x13-x14, x3-x5 <- (AH+AL) x (BH+BL) - ALxBL - AHxBH -+ subs x8, x8, x20 -+ sbcs x9, x9, x21 -+ sbcs x10, x10, x22 -+ sbcs x19, x19, x23 -+ sbcs x15, x15, x24 -+ sbcs x16, x16, x25 -+ sbcs x17, x17, x26 -+ sbcs x18, x18, x27 -+ sbc x7, x7, xzr -+ -+ stp x8, x9, [x2,#32] -+ stp x10, x19, [x2,#48] -+ -+ adds x1, x1, #1 -+ adcs x15, x15, x20 -+ adcs x16, x16, x21 -+ adcs x17, x17, x22 -+ adcs x18, x18, x23 -+ adcs x24, x7, x24 -+ adcs x25, x25, xzr -+ adcs x26, x26, xzr -+ adc x27, x27, xzr -+ -+ stp x15, x16, [x2,#64] -+ stp x17, x18, [x2,#80] -+ stp x24, x25, [x2,#96] -+ stp x26, x27, [x2,#112] -+ -+ ldp x19, x20, [sp,#0] -+ ldp x21, x22, [sp,#16] -+ ldp x23, x24, [sp,#32] -+ ldp x25, x26, [sp,#48] -+ ldp x27, x28, [sp,#64] -+ ldr x29, [sp,#80] -+ add sp, sp, #96 -+ ret -+ -+ -+//////////////////////////////////////////// MACRO -+.macro MUL128x256_COMBA_CUT A0, A1, B0, B1, B2, B3, C0, C1, C2, C3, C4, C5, T0, T1, T2, T3 -+ mul \T0, \A1, \B0 -+ umulh \T1, \A1, \B0 -+ adds \C1, \C1, \C3 -+ adc \C2, \C2, xzr -+ -+ mul \T2, \A0, \B2 -+ umulh \T3, \A0, \B2 -+ adds \C1, \C1, \T0 -+ adcs \C2, \C2, \T1 -+ adc \C3, xzr, xzr -+ -+ mul \T0, \A1, \B1 -+ umulh \T1, \A1, \B1 -+ adds \C2, \C2, \T2 -+ adcs \C3, \C3, \T3 -+ adc \C4, xzr, xzr -+ -+ mul \T2, \A0, \B3 -+ umulh \T3, \A0, \B3 -+ adds \C2, \C2, \T0 -+ adcs \C3, \C3, \T1 -+ adc \C4, \C4, xzr -+ -+ mul \T0, \A1, \B2 -+ umulh \T1, \A1, \B2 -+ adds \C3, \C3, \T2 -+ adcs \C4, \C4, \T3 -+ adc \C5, xzr, xzr -+ -+ mul \T2, \A1, \B3 -+ umulh \T3, \A1, \B3 -+ adds \C3, \C3, \T0 -+ adcs \C4, \C4, \T1 -+ adc \C5, \C5, xzr -+ adds \C4, \C4, \T2 -+ adc \C5, \C5, \T3 -+.endm -+ -+ -+//************************************************************************************** -+// Montgomery reduction -+// Based on method described in Faz-Hernandez et al. https://eprint.iacr.org/2017/1015 -+// Operation: mc [x1] = ma [x0] -+// NOTE: ma=mc is not allowed -+//************************************************************************************** -+.global rdc503_asm -+rdc503_asm: -+ sub sp, sp, #96 -+ stp x19, x20, [sp] -+ stp x21, x22, [sp, #16] -+ stp x23, x24, [sp, #32] -+ stp x25, x26, [sp, #48] -+ stp x27, x28, [sp, #64] -+ stp x29, x30, [sp, #80] -+ -+ ldp x2, x3, [x0,#0] // a[0-1] -+ -+ // Load the prime constant -+ ldr x24, =P503P1_NZ_S8_0 -+ ldr x25, =P503P1_NZ_S8_1 -+ ldr x26, =P503P1_NZ_S8_2 -+ ldr x27, =P503P1_NZ_S8_3 -+ -+ // a[0-1] x p503p1_nz_s8 --> result: x4:x9 -+ mul x4, x2, x24 // a[0] x p503p1_nz_s8[0] -+ umulh x7, x2, x24 -+ mul x5, x2, x25 // a[0] x p503p1_nz_s8[1] -+ umulh x6, x2, x25 -+ MUL128x256_COMBA_CUT x2, x3, x24, x25, x26, x27, x4, x5, x6, x7, x8, x9, x28, x29, x30, x10 -+ -+ ldp x3, x11, [x0,#16] // a[2] -+ ldp x12, x13, [x0,#32] -+ ldp x14, x15, [x0,#48] -+ -+ orr x10, xzr, x9, lsr #8 -+ lsl x9, x9, #56 -+ orr x9, x9, x8, lsr #8 -+ lsl x8, x8, #56 -+ orr x8, x8, x7, lsr #8 -+ lsl x7, x7, #56 -+ orr x7, x7, x6, lsr #8 -+ lsl x6, x6, #56 -+ orr x6, x6, x5, lsr #8 -+ lsl x5, x5, #56 -+ orr x5, x5, x4, lsr #8 -+ lsl x4, x4, #56 -+ -+ adds x11, x4, x11 // a[3] -+ adcs x12, x5, x12 // a[4] -+ adcs x13, x6, x13 -+ adcs x14, x7, x14 -+ adcs x15, x8, x15 -+ ldp x16, x17, [x0,#64] -+ ldp x18, x19, [x0,#80] -+ mul x4, x3, x24 // a[2] x p503p1_nz_s8[0] -+ umulh x7, x3, x24 -+ adcs x16, x9, x16 -+ adcs x17, x10, x17 -+ adcs x18, xzr, x18 -+ adcs x19, xzr, x19 -+ ldp x20, x21, [x0,#96] -+ ldp x22, x23, [x0,#112] -+ mul x5, x3, x25 // a[2] x p503p1_nz_s8[1] -+ umulh x6, x3, x25 -+ adcs x20, xzr, x20 -+ adcs x21, xzr, x21 -+ adcs x22, xzr, x22 -+ adc x23, xzr, x23 -+ -+ // a[2-3] x p503p1_nz_s8 --> result: x4:x9 -+ MUL128x256_COMBA_CUT x3, x11, x24, x25, x26, x27, x4, x5, x6, x7, x8, x9, x28, x29, x30, x10 -+ -+ orr x10, xzr, x9, lsr #8 -+ lsl x9, x9, #56 -+ orr x9, x9, x8, lsr #8 -+ lsl x8, x8, #56 -+ orr x8, x8, x7, lsr #8 -+ lsl x7, x7, #56 -+ orr x7, x7, x6, lsr #8 -+ lsl x6, x6, #56 -+ orr x6, x6, x5, lsr #8 -+ lsl x5, x5, #56 -+ orr x5, x5, x4, lsr #8 -+ lsl x4, x4, #56 -+ -+ adds x13, x4, x13 // a[5] -+ adcs x14, x5, x14 // a[6] -+ adcs x15, x6, x15 -+ adcs x16, x7, x16 -+ mul x4, x12, x24 // a[4] x p503p1_nz_s8[0] -+ umulh x7, x12, x24 -+ adcs x17, x8, x17 -+ adcs x18, x9, x18 -+ adcs x19, x10, x19 -+ adcs x20, xzr, x20 -+ mul x5, x12, x25 // a[4] x p503p1_nz_s8[1] -+ umulh x6, x12, x25 -+ adcs x21, xzr, x21 -+ adcs x22, xzr, x22 -+ adc x23, xzr, x23 -+ -+ // a[4-5] x p503p1_nz_s8 --> result: x4:x9 -+ MUL128x256_COMBA_CUT x12, x13, x24, x25, x26, x27, x4, x5, x6, x7, x8, x9, x28, x29, x30, x10 -+ -+ orr x10, xzr, x9, lsr #8 -+ lsl x9, x9, #56 -+ orr x9, x9, x8, lsr #8 -+ lsl x8, x8, #56 -+ orr x8, x8, x7, lsr #8 -+ lsl x7, x7, #56 -+ orr x7, x7, x6, lsr #8 -+ lsl x6, x6, #56 -+ orr x6, x6, x5, lsr #8 -+ lsl x5, x5, #56 -+ orr x5, x5, x4, lsr #8 -+ lsl x4, x4, #56 -+ -+ adds x15, x4, x15 // a[7] -+ adcs x16, x5, x16 // a[8] -+ adcs x17, x6, x17 -+ adcs x18, x7, x18 -+ mul x4, x14, x24 // a[6] x p503p1_nz_s8[0] -+ umulh x7, x14, x24 -+ adcs x19, x8, x19 -+ adcs x20, x9, x20 -+ adcs x21, x10, x21 -+ mul x5, x14, x25 // a[6] x p503p1_nz_s8[1] -+ umulh x6, x14, x25 -+ adcs x22, xzr, x22 -+ adc x23, xzr, x23 -+ -+ // a[6-7] x p503p1_nz_s8 --> result: x4:x9 -+ MUL128x256_COMBA_CUT x14, x15, x24, x25, x26, x27, x4, x5, x6, x7, x8, x9, x28, x29, x30, x10 -+ -+ orr x10, xzr, x9, lsr #8 -+ lsl x9, x9, #56 -+ orr x9, x9, x8, lsr #8 -+ lsl x8, x8, #56 -+ orr x8, x8, x7, lsr #8 -+ lsl x7, x7, #56 -+ orr x7, x7, x6, lsr #8 -+ lsl x6, x6, #56 -+ orr x6, x6, x5, lsr #8 -+ lsl x5, x5, #56 -+ orr x5, x5, x4, lsr #8 -+ lsl x4, x4, #56 -+ -+ adds x17, x4, x17 -+ adcs x18, x5, x18 -+ adcs x19, x6, x19 -+ adcs x20, x7, x20 -+ stp x16, x17, [x1,#0] // Final result -+ stp x18, x19, [x1,#16] -+ adcs x21, x8, x21 -+ adcs x22, x9, x22 -+ adc x23, x10, x23 -+ stp x20, x21, [x1,#32] -+ stp x22, x23, [x1,#48] -+ -+ ldp x19, x20, [sp] -+ ldp x21, x22, [sp, #16] -+ ldp x23, x24, [sp, #32] -+ ldp x25, x26, [sp, #48] -+ ldp x27, x28, [sp, #64] -+ ldp x29, x30, [sp, #80] -+ add sp, sp, #96 -+ ret -+ -+ -+//*********************************************************************** -+// 503-bit multiprecision addition -+// Operation: c [x2] = a [x0] + b [x1] -+//*********************************************************************** -+.global mp_add503_asm -+mp_add503_asm: -+ ldp x3, x4, [x0,#0] -+ ldp x5, x6, [x0,#16] -+ ldp x11, x12, [x1,#0] -+ ldp x13, x14, [x1,#16] -+ -+ adds x3, x3, x11 -+ adcs x4, x4, x12 -+ adcs x5, x5, x13 -+ adcs x6, x6, x14 -+ ldp x7, x8, [x0,#32] -+ ldp x9, x10, [x0,#48] -+ ldp x15, x16, [x1,#32] -+ ldp x17, x18, [x1,#48] -+ adcs x7, x7, x15 -+ adcs x8, x8, x16 -+ adcs x9, x9, x17 -+ adc x10, x10, x18 -+ -+ stp x3, x4, [x2,#0] -+ stp x5, x6, [x2,#16] -+ stp x7, x8, [x2,#32] -+ stp x9, x10, [x2,#48] -+ ret -+ -+ -+//*********************************************************************** -+// 2x503-bit multiprecision addition -+// Operation: c [x2] = a [x0] + b [x1] -+//*********************************************************************** -+.global mp_add503x2_asm -+mp_add503x2_asm: -+ ldp x3, x4, [x0,#0] -+ ldp x5, x6, [x0,#16] -+ ldp x11, x12, [x1,#0] -+ ldp x13, x14, [x1,#16] -+ adds x3, x3, x11 -+ adcs x4, x4, x12 -+ adcs x5, x5, x13 -+ adcs x6, x6, x14 -+ ldp x7, x8, [x0,#32] -+ ldp x9, x10, [x0,#48] -+ ldp x15, x16, [x1,#32] -+ ldp x17, x18, [x1,#48] -+ adcs x7, x7, x15 -+ adcs x8, x8, x16 -+ adcs x9, x9, x17 -+ adcs x10, x10, x18 -+ -+ stp x3, x4, [x2,#0] -+ stp x5, x6, [x2,#16] -+ stp x7, x8, [x2,#32] -+ stp x9, x10, [x2,#48] -+ -+ ldp x3, x4, [x0,#64] -+ ldp x5, x6, [x0,#80] -+ ldp x11, x12, [x1,#64] -+ ldp x13, x14, [x1,#80] -+ adcs x3, x3, x11 -+ adcs x4, x4, x12 -+ adcs x5, x5, x13 -+ adcs x6, x6, x14 -+ ldp x7, x8, [x0,#96] -+ ldp x9, x10, [x0,#112] -+ ldp x15, x16, [x1,#96] -+ ldp x17, x18, [x1,#112] -+ adcs x7, x7, x15 -+ adcs x8, x8, x16 -+ adcs x9, x9, x17 -+ adc x10, x10, x18 -+ -+ stp x3, x4, [x2,#64] -+ stp x5, x6, [x2,#80] -+ stp x7, x8, [x2,#96] -+ stp x9, x10, [x2,#112] -+ ret -+ -+ -+//*********************************************************************** -+// 2x503-bit multiprecision subtraction -+// Operation: c [x2] = a [x0] - b [x1]. Returns borrow mask -+//*********************************************************************** -+.global mp_sub503x2_asm -+mp_sub503x2_asm: -+ ldp x3, x4, [x0,#0] -+ ldp x5, x6, [x0,#16] -+ ldp x11, x12, [x1,#0] -+ ldp x13, x14, [x1,#16] -+ subs x3, x3, x11 -+ sbcs x4, x4, x12 -+ sbcs x5, x5, x13 -+ sbcs x6, x6, x14 -+ ldp x7, x8, [x0,#32] -+ ldp x9, x10, [x0,#48] -+ ldp x15, x16, [x1,#32] -+ ldp x17, x18, [x1,#48] -+ sbcs x7, x7, x15 -+ sbcs x8, x8, x16 -+ sbcs x9, x9, x17 -+ sbcs x10, x10, x18 -+ -+ stp x3, x4, [x2,#0] -+ stp x5, x6, [x2,#16] -+ stp x7, x8, [x2,#32] -+ stp x9, x10, [x2,#48] -+ -+ ldp x3, x4, [x0,#64] -+ ldp x5, x6, [x0,#80] -+ ldp x11, x12, [x1,#64] -+ ldp x13, x14, [x1,#80] -+ sbcs x3, x3, x11 -+ sbcs x4, x4, x12 -+ sbcs x5, x5, x13 -+ sbcs x6, x6, x14 -+ ldp x7, x8, [x0,#96] -+ ldp x9, x10, [x0,#112] -+ ldp x15, x16, [x1,#96] -+ ldp x17, x18, [x1,#112] -+ sbcs x7, x7, x15 -+ sbcs x8, x8, x16 -+ sbcs x9, x9, x17 -+ sbcs x10, x10, x18 -+ sbc x0, xzr, xzr -+ -+ stp x3, x4, [x2,#64] -+ stp x5, x6, [x2,#80] -+ stp x7, x8, [x2,#96] -+ stp x9, x10, [x2,#112] -+ ret -+ -+ -+//*********************************************************************** -+// Double 2x503-bit multiprecision subtraction -+// Operation: c [x2] = c [x2] - a [x0] - b [x1] -+//*********************************************************************** -+.global mp_dblsub503x2_asm -+mp_dblsub503x2_asm: -+ sub sp, sp, #32 -+ stp x27, x28, [sp, #0] -+ stp x29, x30, [sp, #16] -+ ldp x3, x4, [x2,#0] -+ ldp x5, x6, [x2,#16] -+ ldp x7, x8, [x2,#32] -+ ldp x9, x10, [x2,#48] -+ ldp x11, x12, [x2,#64] -+ ldp x13, x14, [x2,#80] -+ ldp x15, x16, [x2,#96] -+ ldp x17, x18, [x2,#112] -+ -+ ldp x27, x28, [x0,#0] -+ ldp x29, x30, [x0,#16] -+ subs x3, x3, x27 -+ sbcs x4, x4, x28 -+ sbcs x5, x5, x29 -+ sbcs x6, x6, x30 -+ ldp x27, x28, [x0,#32] -+ ldp x29, x30, [x0,#48] -+ sbcs x7, x7, x27 -+ sbcs x8, x8, x28 -+ sbcs x9, x9, x29 -+ sbcs x10, x10, x30 -+ ldp x27, x28, [x0,#64] -+ ldp x29, x30, [x0,#80] -+ sbcs x11, x11, x27 -+ sbcs x12, x12, x28 -+ sbcs x13, x13, x29 -+ sbcs x14, x14, x30 -+ ldp x27, x28, [x0,#96] -+ ldp x29, x30, [x0,#112] -+ sbcs x15, x15, x27 -+ sbcs x16, x16, x28 -+ sbcs x17, x17, x29 -+ sbc x18, x18, x30 -+ -+ ldp x27, x28, [x1,#0] -+ ldp x29, x30, [x1,#16] -+ subs x3, x3, x27 -+ sbcs x4, x4, x28 -+ sbcs x5, x5, x29 -+ sbcs x6, x6, x30 -+ ldp x27, x28, [x1,#32] -+ ldp x29, x30, [x1,#48] -+ sbcs x7, x7, x27 -+ sbcs x8, x8, x28 -+ sbcs x9, x9, x29 -+ sbcs x10, x10, x30 -+ ldp x27, x28, [x1,#64] -+ ldp x29, x30, [x1,#80] -+ sbcs x11, x11, x27 -+ sbcs x12, x12, x28 -+ sbcs x13, x13, x29 -+ sbcs x14, x14, x30 -+ ldp x27, x28, [x1,#96] -+ ldp x29, x30, [x1,#112] -+ sbcs x15, x15, x27 -+ sbcs x16, x16, x28 -+ sbcs x17, x17, x29 -+ sbc x18, x18, x30 -+ -+ stp x3, x4, [x2,#0] -+ stp x5, x6, [x2,#16] -+ stp x7, x8, [x2,#32] -+ stp x9, x10, [x2,#48] -+ stp x11, x12, [x2,#64] -+ stp x13, x14, [x2,#80] -+ stp x15, x16, [x2,#96] -+ stp x17, x18, [x2,#112] -+ -+ ldp x27, x28, [sp, #0] -+ ldp x29, x30, [sp, #16] -+ add sp, sp, #32 -+ ret -diff --git a/third_party/sidh/src/P503.c b/third_party/sidh/src/P503.c -new file mode 100644 -index 000000000..fab51a38b ---- /dev/null -+++ b/third_party/sidh/src/P503.c -@@ -0,0 +1,99 @@ -+/******************************************************************************************** -+* SIDH: an efficient supersingular isogeny cryptography library -+* -+* Abstract: supersingular isogeny parameters and generation of functions for P503 -+*********************************************************************************************/ -+ -+#include "sidh/def_p503.h" -+#include "sidh/P503_api.h" -+#include "P503_internal.h" -+ -+// Encoding of field elements, elements over Z_order, elements over GF(p^2) and elliptic curve points: -+// -------------------------------------------------------------------------------------------------- -+// Elements over GF(p) and Z_order are encoded with the least significant octet (and digit) located at the leftmost position (i.e., little endian format). -+// Elements (a+b*i) over GF(p^2), where a and b are defined over GF(p), are encoded as {a, b}, with a in the least significant position. -+// Elliptic curve points P = (x,y) are encoded as {x, y}, with x in the least significant position. -+// Internally, the number of digits used to represent all these elements is obtained by approximating the number of bits to the immediately greater multiple of 32. -+// For example, a 503-bit field element is represented with Ceil(503 / 64) = 8 64-bit digits or Ceil(503 / 32) = 16 32-bit digits. -+ -+// -+// Curve isogeny system "SIDHp503". Base curve: Montgomery curve By^2 = Cx^3 + Ax^2 + Cx defined over GF(p503^2), where A=0, B=1, C=1 and p503 = 2^250*3^159-1 -+// -+ -+const struct params_t kP503Params = { -+ .prime = { -+ 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xABFFFFFFFFFFFFFF, -+ 0x13085BDA2211E7A0, 0x1B9BF6C87B7E7DAF, 0x6045C6BDDA77A4D0, 0x004066F541811E1E -+ }, -+ -+ .primeP1 = { -+ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xAC00000000000000, -+ 0x13085BDA2211E7A0, 0x1B9BF6C87B7E7DAF, 0x6045C6BDDA77A4D0, 0x004066F541811E1E -+ }, -+ .primeX2 = { -+ 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x57FFFFFFFFFFFFFF, -+ 0x2610B7B44423CF41, 0x3737ED90F6FCFB5E, 0xC08B8D7BB4EF49A0, 0x0080CDEA83023C3C -+ }, -+ .Alice_order = { -+ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0400000000000000 -+ }, -+ .Bob_order = { -+ 0xC216F6888479E82B, 0xE6FDB21EDF9F6BC4, 0x1171AF769DE93406, 0x1019BD5060478798 -+ }, -+ .A_gen = { -+ 0xE7EF4AA786D855AF, 0xED5758F03EB34D3B, 0x09AE172535A86AA9, 0x237B9CC07D622723, -+ 0xE3A284CBA4E7932D, 0x27481D9176C5E63F, 0x6A323FF55C6E71BF, 0x002ECC31A6FB8773, // XPA0 -+ 0x64D02E4E90A620B8, 0xDAB8128537D4B9F1, 0x4BADF77B8A228F98, 0x0F5DBDF9D1FB7D1B, -+ 0xBEC4DB288E1A0DCC, 0xE76A8665E80675DB, 0x6D6F252E12929463, 0x003188BD1463FACC, // XPA1 -+ 0xB79D41025DE85D56, 0x0B867DA9DF169686, 0x740E5368021C827D, 0x20615D72157BF25C, -+ 0xFF1590013C9B9F5B, 0xC884DCADE8C16CEA, 0xEBD05E53BF724E01, 0x0032FEF8FDA5748C, // XQA0 -+ 0x12E2E849AA0A8006, 0x41CF47008635A1E8, 0x9CD720A70798AED7, 0x42A820B42FCF04CF, -+ 0x7BF9BAD32AAE88B1, 0xF619127A54090BBE, 0x1CB10D8F56408EAA, 0x001D6B54C3C0EDEB, // XRA0 -+ 0x34DB54931CBAAC36, 0x420A18CB8DD5F0C4, 0x32008C1A48C0F44D, 0x3B3BA772B1CFD44D, -+ 0xA74B058FDAF13515, 0x095FC9CA7EEC17B4, 0x448E829D28F120F8, 0x00261EC3ED16A489 // XRA1 -+ }, -+ .B_gen = { -+ 0x7EDE37F4FA0BC727, 0xF7F8EC5C8598941C, 0xD15519B516B5F5C8, 0xF6D5AC9B87A36282, -+ 0x7B19F105B30E952E, 0x13BD8B2025B4EBEE, 0x7B96D27F4EC579A2, 0x00140850CAB7E5DE, // XPB0 -+ 0x7764909DAE7B7B2D, 0x578ABB16284911AB, 0x76E2BFD146A6BF4D, 0x4824044B23AA02F0, -+ 0x1105048912A321F3, 0xB8A2E482CF0F10C1, 0x42FF7D0BE2152085, 0x0018E599C5223352, // XPB1 -+ 0x4256C520FB388820, 0x744FD7C3BAAF0A13, 0x4B6A2DDDB12CBCB8, 0xE46826E27F427DF8, -+ 0xFE4A663CD505A61B, 0xD6B3A1BAF025C695, 0x7C3BB62B8FCC00BD, 0x003AFDDE4A35746C, // XQB0 -+ 0x75601CD1E6C0DFCB, 0x1A9007239B58F93E, 0xC1F1BE80C62107AC, 0x7F513B898F29FF08, -+ 0xEA0BEDFF43E1F7B2, 0x2C6D94018CBAE6D0, 0x3A430D31BCD84672, 0x000D26892ECCFE83, // XRB0 -+ 0x1119D62AEA3007A1, 0xE3702AA4E04BAE1B, 0x9AB96F7D59F990E7, 0xF58440E8B43319C0, -+ 0xAF8134BEE1489775, 0xE7F7774E905192AA, 0xF54AE09308E98039, 0x001EF7A041A86112 // XRB1 -+ }, -+ .Montgomery_R2 = { -+ 0x5289A0CF641D011F, 0x9B88257189FED2B9, 0xA3B365D58DC8F17A, 0x5BC57AB6EFF168EC, -+ 0x9E51998BD84D4423, 0xBF8999CBAC3B5695, 0x46E9127BCE14CDB6, 0x003F6CFCE8B81771 -+ }, -+ .Montgomery_one = { -+ 0x00000000000003F9, 0x0000000000000000, 0x0000000000000000, 0xB400000000000000, -+ 0x63CB1A6EA6DED2B4, 0x51689D8D667EB37D, 0x8ACD77C71AB24142, 0x0026FBAEC60F5953 -+ }, -+ .Montgomery_Rprime = { -+ 0x0C2615CA3C5BAA99, 0x5A4FF3072AB6AA6A, 0xA6AFD4B039AD6AA2, 0x010DA06A26DD05CB -+ }, -+ .Montgomery_rprime = { -+ 0x49C8A87190C0697D, 0x2EB7968EA0F0A558, 0x944257B696777FA2, 0xBAA4DDCD6139D2B3 -+ }, -+ .Border_div3 = { -+ 0xEB5CFCD82C28A2B9, 0x4CFF3B5F9FDFCE96, 0xB07B3A7CDF4DBC02, 0x055DE9C5756D2D32 -+ }, -+ .strat_Alice = { -+ 61, 32, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, -+ 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, -+ 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 29, 16, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, -+ 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 13, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, -+ 1, 1, 2, 1, 1, 5, 4, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1 -+ }, -+ .strat_Bob = { -+ 71, 38, 21, 13, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 5, 4, 2, 1, 1, 2, 1, -+ 1, 2, 1, 1, 1, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 17, 9, -+ 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 1, 2, 1, -+ 1, 4, 2, 1, 1, 2, 1, 1, 33, 17, 9, 5, 3, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 2, 1, 1, 1, -+ 2, 1, 1, 8, 4, 2, 1, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1, 16, 8, 4, 2, 1, 1, 1, 2, -+ 1, 1, 4, 2, 1, 1, 2, 1, 1, 8, 4, 2, 1, 1, 2, 1, 1, 4, 2, 1, 1, 2, 1, 1 -+ } -+}; -diff --git a/third_party/sidh/src/P503_internal.h b/third_party/sidh/src/P503_internal.h -new file mode 100644 -index 000000000..67aed146c ---- /dev/null -+++ b/third_party/sidh/src/P503_internal.h -@@ -0,0 +1,279 @@ -+/******************************************************************************************** -+* SIDH: an efficient supersingular isogeny cryptography library -+* -+* Abstract: internal header file for P503 -+*********************************************************************************************/ -+ -+#ifndef P503_INTERNAL_H__ -+#define P503_INTERNAL_H__ -+ -+#include -+#include "sidh/def_p503.h" -+ -+// Macro definitions -+#define NBITS_TO_NBYTES(nbits) (((nbits)+7)/8) // Conversion macro from number of bits to number of bytes -+#define NBITS_TO_NWORDS(nbits) (((nbits)+(sizeof(digit_t)*8)-1)/(sizeof(digit_t)*8)) // Conversion macro from number of bits to number of computer words -+#define NBYTES_TO_NWORDS(nbytes) (((nbytes)+sizeof(digit_t)-1)/sizeof(digit_t)) // Conversion macro from number of bytes to number of computer words -+ -+// Macro to avoid compiler warnings when detecting unreferenced parameters -+#define UNREFERENCED_PARAMETER(PAR) ((void)(PAR)) -+ -+// SIDH Basic, internally used, constants -+#define MAXBITS_FIELD 512 -+#define MAXWORDS_FIELD ((MAXBITS_FIELD+RADIX-1)/RADIX) // Max. number of words to represent field elements -+#define MAXBITS_ORDER NBITS_ORDER -+#define MAXWORDS_ORDER ((MAXBITS_ORDER+RADIX-1)/RADIX) // Max. number of words to represent elements in [1, oA-1] or [1, oB]. -+#define ALICE 0 -+#define BOB 1 -+#define OALICE_BITS 250 -+#define OBOB_BITS 253 -+#define OBOB_EXPON 159 -+// Fixed parameters for isogeny tree computation -+#define MAX_INT_POINTS_ALICE 7 -+#define MAX_INT_POINTS_BOB 8 -+#define FP2_ENCODED_BYTES 2*((NBITS_FIELD + 7) / 8) -+ -+// Setting up macro defines and including GF(p), GF(p^2), curve, isogeny and kex functions -+#define fpcopy fpcopy503 -+#define fpzero fpzero503 -+#define fpadd fpadd503 -+#define fpsub fpsub503 -+#define fpneg fpneg503 -+#define fpdiv2 fpdiv2_503 -+#define fpcorrection fpcorrection503 -+#define fpmul_mont fpmul503_mont -+#define fpsqr_mont fpsqr503_mont -+#define fpinv_mont fpinv503_mont -+#define fpinv_chain_mont fpinv503_chain_mont -+#define fpinv_mont_bingcd fpinv503_mont_bingcd -+#define fp2copy fp2copy503 -+#define fp2zero fp2zero503 -+#define fp2add fp2add503 -+#define fp2sub fp2sub503 -+#define fp2neg fp2neg503 -+#define fp2div2 fp2div2_503 -+#define fp2correction fp2correction503 -+#define fp2mul_mont fp2mul503_mont -+#define fp2sqr_mont fp2sqr503_mont -+#define fp2inv_mont fp2inv503_mont -+#define fp2inv_mont_bingcd fp2inv503_mont_bingcd -+#define fpequal_non_constant_time fpequal503_non_constant_time -+#define cswap_asm cswap503_asm -+#define mp_add_asm mp_add503_asm -+#define mp_subx2_asm mp_sub503x2_asm -+#define mp_dblsubx2_asm mp_dblsub503x2_asm -+#define crypto_kem_keypair crypto_kem_keypair_SIKEp503 -+#define crypto_kem_enc crypto_kem_enc_SIKEp503 -+#define crypto_kem_dec crypto_kem_dec_SIKEp503 -+#define random_mod_order_A random_mod_order_A_SIDHp503 -+#define random_mod_order_B random_mod_order_B_SIDHp503 -+#define EphemeralKeyGeneration_A EphemeralKeyGeneration_A_SIDHp503 -+#define EphemeralKeyGeneration_B EphemeralKeyGeneration_B_SIDHp503 -+#define EphemeralSecretAgreement_A EphemeralSecretAgreement_A_SIDHp503 -+#define EphemeralSecretAgreement_B EphemeralSecretAgreement_B_SIDHp503 -+ -+// SIDH's basic element definitions and point representations -+ -+typedef digit_t felm_t[NWORDS_FIELD]; // Datatype for representing 503-bit field elements (512-bit max.) -+typedef digit_t dfelm_t[2*NWORDS_FIELD]; // Datatype for representing double-precision 2x503-bit field elements (512-bit max.) -+ -+/* An element in F_{p^2}, is composed of two coefficients -+ from F_p, * i.e. Fp2 element = c0 + c1*i in F_{p^2} -+ */ -+typedef struct { -+ felm_t c0; -+ felm_t c1; -+} fp2; -+ -+// Our F_{p^2} element type is a pointer to the struct. -+typedef fp2 f2elm_t[1]; -+ -+typedef struct { f2elm_t X; f2elm_t Z; } point_proj; // Point representation in projective XZ Montgomery coordinates. -+typedef point_proj point_proj_t[1]; -+ -+/* Old GCC 4.9 (jessie) doesn't implement {0} initialization properly, -+ which violates C11 as described in 6.7.9, 21 (similarily C99, 6.7.8). -+ Defines below are used to work around the bug, and provide a way -+ to initialize f2elem_t and point_proj_t structs. -+ Bug has been fixed in GCC6 (debian stretch). -+*/ -+#define F2ELM_INIT {{ {0}, {0} }} -+#define POINT_PROJ_INIT {{ F2ELM_INIT, F2ELM_INIT }} -+ -+/**************** Function prototypes ****************/ -+/************* Multiprecision functions **************/ -+ -+// Copy wordsize digits, c = a, where lng(a) = nwords -+void copy_words(const digit_t* a, digit_t* c, const unsigned int nwords); -+ -+// Multiprecision addition, c = a+b, where lng(a) = lng(b) = nwords. Returns the carry bit -+unsigned int mp_add(const digit_t* a, const digit_t* b, digit_t* c, const unsigned int nwords); -+ -+// 503-bit multiprecision addition, c = a+b -+void mp_add503(const digit_t* a, const digit_t* b, digit_t* c); -+void mp_add503_asm(const digit_t* a, const digit_t* b, digit_t* c); -+void cswap503_asm(point_proj_t x, point_proj_t y, const digit_t option); -+ -+// Multiprecision subtraction, c = a-b, where lng(a) = lng(b) = nwords. Returns the borrow bit -+unsigned int mp_sub(const digit_t* a, const digit_t* b, digit_t* c, const unsigned int nwords); -+digit_t mp_sub503x2_asm(const digit_t* a, const digit_t* b, digit_t* c); -+ -+// Double 2x503-bit multiprecision subtraction, c = c-a-b, where c > a and c > b -+void mp_dblsub503x2_asm(const digit_t* a, const digit_t* b, digit_t* c); -+ -+// Multiprecision left shift -+void mp_shiftleft(digit_t* x, unsigned int shift, const unsigned int nwords); -+ -+// Multiprecision right shift by one -+void mp_shiftr1(digit_t* x, const unsigned int nwords); -+ -+// Multiprecision left right shift by one -+void mp_shiftl1(digit_t* x, const unsigned int nwords); -+ -+// Digit multiplication, digit * digit -> 2-digit result -+void digit_x_digit(const digit_t a, const digit_t b, digit_t* c); -+ -+// Multiprecision comba multiply, c = a*b, where lng(a) = lng(b) = nwords. -+void mp_mul(const digit_t* a, const digit_t* b, digit_t* c, const unsigned int nwords); -+ -+/************ Field arithmetic functions *************/ -+ -+// Copy of a field element, c = a -+void fpcopy503(const digit_t* a, digit_t* c); -+ -+// Zeroing a field element, a = 0 -+void fpzero503(digit_t* a); -+ -+// Non constant-time comparison of two field elements. If a = b return TRUE, otherwise, return FALSE -+bool fpequal503_non_constant_time(const digit_t* a, const digit_t* b); -+ -+// Modular addition, c = a+b mod p503 -+extern void fpadd503(const digit_t* a, const digit_t* b, digit_t* c); -+extern void fpadd503_asm(const digit_t* a, const digit_t* b, digit_t* c); -+ -+// Modular subtraction, c = a-b mod p503 -+extern void fpsub503(const digit_t* a, const digit_t* b, digit_t* c); -+extern void fpsub503_asm(const digit_t* a, const digit_t* b, digit_t* c); -+ -+// Modular negation, a = -a mod p503 -+extern void fpneg503(digit_t* a); -+ -+// Modular division by two, c = a/2 mod p503. -+void fpdiv2_503(const digit_t* a, digit_t* c); -+ -+// Modular correction to reduce field element a in [0, 2*p503-1] to [0, p503-1]. -+void fpcorrection503(digit_t* a); -+ -+// 503-bit Montgomery reduction, c = a mod p -+void rdc_mont(const digit_t* a, digit_t* c); -+ -+// Field multiplication using Montgomery arithmetic, c = a*b*R^-1 mod p503, where R=2^768 -+void fpmul503_mont(const digit_t* a, const digit_t* b, digit_t* c); -+void mul503_asm(const digit_t* a, const digit_t* b, digit_t* c); -+void rdc503_asm(const digit_t* ma, digit_t* mc); -+ -+// Field squaring using Montgomery arithmetic, c = a*b*R^-1 mod p503, where R=2^768 -+void fpsqr503_mont(const digit_t* ma, digit_t* mc); -+ -+// Conversion to Montgomery representation -+void to_mont(const digit_t* a, digit_t* mc); -+ -+// Conversion from Montgomery representation to standard representation -+void from_mont(const digit_t* ma, digit_t* c); -+ -+// Field inversion, a = a^-1 in GF(p503) -+void fpinv503_mont(digit_t* a); -+ -+// Field inversion, a = a^-1 in GF(p503) using the binary GCD -+void fpinv503_mont_bingcd(digit_t* a); -+ -+// Chain to compute (p503-3)/4 using Montgomery arithmetic -+void fpinv503_chain_mont(digit_t* a); -+ -+/************ GF(p^2) arithmetic functions *************/ -+ -+// Copy of a GF(p503^2) element, c = a -+void fp2copy503(const f2elm_t a, f2elm_t c); -+ -+// Zeroing a GF(p503^2) element, a = 0 -+void fp2zero503(f2elm_t a); -+ -+// GF(p503^2) negation, a = -a in GF(p503^2) -+void fp2neg503(f2elm_t a); -+ -+// GF(p503^2) addition, c = a+b in GF(p503^2) -+extern void fp2add503(const f2elm_t a, const f2elm_t b, f2elm_t c); -+ -+// GF(p503^2) subtraction, c = a-b in GF(p503^2) -+extern void fp2sub503(const f2elm_t a, const f2elm_t b, f2elm_t c); -+ -+// GF(p503^2) division by two, c = a/2 in GF(p503^2) -+void fp2div2_503(const f2elm_t a, f2elm_t c); -+ -+// Modular correction, a = a in GF(p503^2) -+void fp2correction503(f2elm_t a); -+ -+// GF(p503^2) squaring using Montgomery arithmetic, c = a^2 in GF(p503^2) -+void fp2sqr503_mont(const f2elm_t a, f2elm_t c); -+ -+// GF(p503^2) multiplication using Montgomery arithmetic, c = a*b in GF(p503^2) -+void fp2mul503_mont(const f2elm_t a, const f2elm_t b, f2elm_t c); -+ -+// Conversion of a GF(p503^2) element to Montgomery representation -+void to_fp2mont(const f2elm_t a, f2elm_t mc); -+ -+// Conversion of a GF(p503^2) element from Montgomery representation to standard representation -+void from_fp2mont(const f2elm_t ma, f2elm_t c); -+ -+// GF(p503^2) inversion using Montgomery arithmetic, a = (a0-i*a1)/(a0^2+a1^2) -+void fp2inv503_mont(f2elm_t a); -+ -+// GF(p503^2) inversion, a = (a0-i*a1)/(a0^2+a1^2), GF(p503) inversion done using the binary GCD -+void fp2inv503_mont_bingcd(f2elm_t a); -+ -+// n-way Montgomery inversion -+void mont_n_way_inv(const f2elm_t* vec, const int n, f2elm_t* out); -+ -+/************ Elliptic curve and isogeny functions *************/ -+ -+// Computes the j-invariant of a Montgomery curve with projective constant. -+void j_inv(const f2elm_t A, const f2elm_t C, f2elm_t jinv); -+ -+// Simultaneous doubling and differential addition. -+void xDBLADD(point_proj_t P, point_proj_t Q, const f2elm_t xPQ, const f2elm_t A24); -+ -+// Doubling of a Montgomery point in projective coordinates (X:Z). -+void xDBL(const point_proj_t P, point_proj_t Q, const f2elm_t A24plus, const f2elm_t C24); -+ -+// Computes [2^e](X:Z) on Montgomery curve with projective constant via e repeated doublings. -+void xDBLe(const point_proj_t P, point_proj_t Q, const f2elm_t A24plus, const f2elm_t C24, const int e); -+ -+// Differential addition. -+void xADD(point_proj_t P, const point_proj_t Q, const f2elm_t xPQ); -+ -+// Computes the corresponding 4-isogeny of a projective Montgomery point (X4:Z4) of order 4. -+void get_4_isog(const point_proj_t P, f2elm_t A24plus, f2elm_t C24, f2elm_t* coeff); -+ -+// Evaluates the isogeny at the point (X:Z) in the domain of the isogeny. -+void eval_4_isog(point_proj_t P, f2elm_t* coeff); -+ -+// Tripling of a Montgomery point in projective coordinates (X:Z). -+void xTPL(const point_proj_t P, point_proj_t Q, const f2elm_t A24minus, const f2elm_t A24plus); -+ -+// Computes [3^e](X:Z) on Montgomery curve with projective constant via e repeated triplings. -+void xTPLe(const point_proj_t P, point_proj_t Q, const f2elm_t A24minus, const f2elm_t A24plus, const int e); -+ -+// Computes the corresponding 3-isogeny of a projective Montgomery point (X3:Z3) of order 3. -+void get_3_isog(const point_proj_t P, f2elm_t A24minus, f2elm_t A24plus, f2elm_t* coeff); -+ -+// Computes the 3-isogeny R=phi(X:Z), given projective point (X3:Z3) of order 3 on a Montgomery curve and a point P with coefficients given in coeff. -+void eval_3_isog(point_proj_t Q, f2elm_t* coeff); -+ -+// 3-way simultaneous inversion -+void inv_3_way(f2elm_t z1, f2elm_t z2, f2elm_t z3); -+ -+// Given the x-coordinates of P, Q, and R, returns the value A corresponding to the Montgomery curve E_A: y^2=x^3+A*x^2+x such that R=Q-P on E_A. -+void get_A(const f2elm_t xP, const f2elm_t xQ, const f2elm_t xR, f2elm_t A); -+ -+ -+#endif -diff --git a/third_party/sidh/src/ec_isogeny.c b/third_party/sidh/src/ec_isogeny.c -new file mode 100644 -index 000000000..c512c5831 ---- /dev/null -+++ b/third_party/sidh/src/ec_isogeny.c -@@ -0,0 +1,270 @@ -+/******************************************************************************************** -+* SIDH: an efficient supersingular isogeny cryptography library -+* -+* Abstract: elliptic curve and isogeny functions -+*********************************************************************************************/ -+#include "sidh/def_p503.h" -+#include "P503_internal.h" -+ -+extern const struct params_t kP503Params; -+ -+void xDBL(const point_proj_t P, point_proj_t Q, const f2elm_t A24plus, const f2elm_t C24) -+{ // Doubling of a Montgomery point in projective coordinates (X:Z). -+ // Input: projective Montgomery x-coordinates P = (X1:Z1), where x1=X1/Z1 and Montgomery curve constants A+2C and 4C. -+ // Output: projective Montgomery x-coordinates Q = 2*P = (X2:Z2). -+ f2elm_t t0, t1; -+ -+ fp2sub(P->X, P->Z, t0); // t0 = X1-Z1 -+ fp2add(P->X, P->Z, t1); // t1 = X1+Z1 -+ fp2sqr_mont(t0, t0); // t0 = (X1-Z1)^2 -+ fp2sqr_mont(t1, t1); // t1 = (X1+Z1)^2 -+ fp2mul_mont(C24, t0, Q->Z); // Z2 = C24*(X1-Z1)^2 -+ fp2mul_mont(t1, Q->Z, Q->X); // X2 = C24*(X1-Z1)^2*(X1+Z1)^2 -+ fp2sub(t1, t0, t1); // t1 = (X1+Z1)^2-(X1-Z1)^2 -+ fp2mul_mont(A24plus, t1, t0); // t0 = A24plus*[(X1+Z1)^2-(X1-Z1)^2] -+ fp2add(Q->Z, t0, Q->Z); // Z2 = A24plus*[(X1+Z1)^2-(X1-Z1)^2] + C24*(X1-Z1)^2 -+ fp2mul_mont(Q->Z, t1, Q->Z); // Z2 = [A24plus*[(X1+Z1)^2-(X1-Z1)^2] + C24*(X1-Z1)^2]*[(X1+Z1)^2-(X1-Z1)^2] -+} -+ -+ -+void xDBLe(const point_proj_t P, point_proj_t Q, const f2elm_t A24plus, const f2elm_t C24, const int e) -+{ // Computes [2^e](X:Z) on Montgomery curve with projective constant via e repeated doublings. -+ // Input: projective Montgomery x-coordinates P = (XP:ZP), such that xP=XP/ZP and Montgomery curve constants A+2C and 4C. -+ // Output: projective Montgomery x-coordinates Q <- (2^e)*P. -+ int i; -+ -+ copy_words((digit_t*)P, (digit_t*)Q, 2*2*NWORDS_FIELD); -+ -+ for (i = 0; i < e; i++) { -+ xDBL(Q, Q, A24plus, C24); -+ } -+} -+ -+ -+void get_4_isog(const point_proj_t P, f2elm_t A24plus, f2elm_t C24, f2elm_t* coeff) -+{ // Computes the corresponding 4-isogeny of a projective Montgomery point (X4:Z4) of order 4. -+ // Input: projective point of order four P = (X4:Z4). -+ // Output: the 4-isogenous Montgomery curve with projective coefficients A+2C/4C and the 3 coefficients -+ // that are used to evaluate the isogeny at a point in eval_4_isog(). -+ -+ fp2sub(P->X, P->Z, coeff[1]); // coeff[1] = X4-Z4 -+ fp2add(P->X, P->Z, coeff[2]); // coeff[2] = X4+Z4 -+ fp2sqr_mont(P->Z, coeff[0]); // coeff[0] = Z4^2 -+ fp2add(coeff[0], coeff[0], coeff[0]); // coeff[0] = 2*Z4^2 -+ fp2sqr_mont(coeff[0], C24); // C24 = 4*Z4^4 -+ fp2add(coeff[0], coeff[0], coeff[0]); // coeff[0] = 4*Z4^2 -+ fp2sqr_mont(P->X, A24plus); // A24plus = X4^2 -+ fp2add(A24plus, A24plus, A24plus); // A24plus = 2*X4^2 -+ fp2sqr_mont(A24plus, A24plus); // A24plus = 4*X4^4 -+} -+ -+ -+void eval_4_isog(point_proj_t P, f2elm_t* coeff) -+{ // Evaluates the isogeny at the point (X:Z) in the domain of the isogeny, given a 4-isogeny phi defined -+ // by the 3 coefficients in coeff (computed in the function get_4_isog()). -+ // Inputs: the coefficients defining the isogeny, and the projective point P = (X:Z). -+ // Output: the projective point P = phi(P) = (X:Z) in the codomain. -+ f2elm_t t0, t1; -+ -+ fp2add(P->X, P->Z, t0); // t0 = X+Z -+ fp2sub(P->X, P->Z, t1); // t1 = X-Z -+ fp2mul_mont(t0, coeff[1], P->X); // X = (X+Z)*coeff[1] -+ fp2mul_mont(t1, coeff[2], P->Z); // Z = (X-Z)*coeff[2] -+ fp2mul_mont(t0, t1, t0); // t0 = (X+Z)*(X-Z) -+ fp2mul_mont(t0, coeff[0], t0); // t0 = coeff[0]*(X+Z)*(X-Z) -+ fp2add(P->X, P->Z, t1); // t1 = (X-Z)*coeff[2] + (X+Z)*coeff[1] -+ fp2sub(P->X, P->Z, P->Z); // Z = (X-Z)*coeff[2] - (X+Z)*coeff[1] -+ fp2sqr_mont(t1, t1); // t1 = [(X-Z)*coeff[2] + (X+Z)*coeff[1]]^2 -+ fp2sqr_mont(P->Z, P->Z); // Z = [(X-Z)*coeff[2] - (X+Z)*coeff[1]]^2 -+ fp2add(t1, t0, P->X); // X = coeff[0]*(X+Z)*(X-Z) + [(X-Z)*coeff[2] + (X+Z)*coeff[1]]^2 -+ fp2sub(P->Z, t0, t0); // t0 = [(X-Z)*coeff[2] - (X+Z)*coeff[1]]^2 - coeff[0]*(X+Z)*(X-Z) -+ fp2mul_mont(P->X, t1, P->X); // Xfinal -+ fp2mul_mont(P->Z, t0, P->Z); // Zfinal -+} -+ -+ -+void xTPL(const point_proj_t P, point_proj_t Q, const f2elm_t A24minus, const f2elm_t A24plus) -+{ // Tripling of a Montgomery point in projective coordinates (X:Z). -+ // Input: projective Montgomery x-coordinates P = (X:Z), where x=X/Z and Montgomery curve constants A24plus = A+2C and A24minus = A-2C. -+ // Output: projective Montgomery x-coordinates Q = 3*P = (X3:Z3). -+ f2elm_t t0, t1, t2, t3, t4, t5, t6; -+ -+ fp2sub(P->X, P->Z, t0); // t0 = X-Z -+ fp2sqr_mont(t0, t2); // t2 = (X-Z)^2 -+ fp2add(P->X, P->Z, t1); // t1 = X+Z -+ fp2sqr_mont(t1, t3); // t3 = (X+Z)^2 -+ fp2add(t0, t1, t4); // t4 = 2*X -+ fp2sub(t1, t0, t0); // t0 = 2*Z -+ fp2sqr_mont(t4, t1); // t1 = 4*X^2 -+ fp2sub(t1, t3, t1); // t1 = 4*X^2 - (X+Z)^2 -+ fp2sub(t1, t2, t1); // t1 = 4*X^2 - (X+Z)^2 - (X-Z)^2 -+ fp2mul_mont(t3, A24plus, t5); // t5 = A24plus*(X+Z)^2 -+ fp2mul_mont(t3, t5, t3); // t3 = A24plus*(X+Z)^3 -+ fp2mul_mont(A24minus, t2, t6); // t6 = A24minus*(X-Z)^2 -+ fp2mul_mont(t2, t6, t2); // t2 = A24minus*(X-Z)^3 -+ fp2sub(t2, t3, t3); // t3 = A24minus*(X-Z)^3 - coeff*(X+Z)^3 -+ fp2sub(t5, t6, t2); // t2 = A24plus*(X+Z)^2 - A24minus*(X-Z)^2 -+ fp2mul_mont(t1, t2, t1); // t1 = [4*X^2 - (X+Z)^2 - (X-Z)^2]*[A24plus*(X+Z)^2 - A24minus*(X-Z)^2] -+ fp2add(t3, t1, t2); // t2 = [4*X^2 - (X+Z)^2 - (X-Z)^2]*[A24plus*(X+Z)^2 - A24minus*(X-Z)^2] + A24minus*(X-Z)^3 - coeff*(X+Z)^3 -+ fp2sqr_mont(t2, t2); // t2 = t2^2 -+ fp2mul_mont(t4, t2, Q->X); // X3 = 2*X*t2 -+ fp2sub(t3, t1, t1); // t1 = A24minus*(X-Z)^3 - A24plus*(X+Z)^3 - [4*X^2 - (X+Z)^2 - (X-Z)^2]*[A24plus*(X+Z)^2 - A24minus*(X-Z)^2] -+ fp2sqr_mont(t1, t1); // t1 = t1^2 -+ fp2mul_mont(t0, t1, Q->Z); // Z3 = 2*Z*t1 -+} -+ -+ -+void xTPLe(const point_proj_t P, point_proj_t Q, const f2elm_t A24minus, const f2elm_t A24plus, const int e) -+{ // Computes [3^e](X:Z) on Montgomery curve with projective constant via e repeated triplings. -+ // Input: projective Montgomery x-coordinates P = (XP:ZP), such that xP=XP/ZP and Montgomery curve constants A24plus = A+2C and A24minus = A-2C. -+ // Output: projective Montgomery x-coordinates Q <- (3^e)*P. -+ int i; -+ -+ copy_words((digit_t*)P, (digit_t*)Q, 2*2*NWORDS_FIELD); -+ -+ for (i = 0; i < e; i++) { -+ xTPL(Q, Q, A24minus, A24plus); -+ } -+} -+ -+ -+void get_3_isog(const point_proj_t P, f2elm_t A24minus, f2elm_t A24plus, f2elm_t* coeff) -+{ // Computes the corresponding 3-isogeny of a projective Montgomery point (X3:Z3) of order 3. -+ // Input: projective point of order three P = (X3:Z3). -+ // Output: the 3-isogenous Montgomery curve with projective coefficient A/C. -+ f2elm_t t0, t1, t2, t3, t4; -+ -+ fp2sub(P->X, P->Z, coeff[0]); // coeff0 = X-Z -+ fp2sqr_mont(coeff[0], t0); // t0 = (X-Z)^2 -+ fp2add(P->X, P->Z, coeff[1]); // coeff1 = X+Z -+ fp2sqr_mont(coeff[1], t1); // t1 = (X+Z)^2 -+ fp2add(t0, t1, t2); // t2 = (X+Z)^2 + (X-Z)^2 -+ fp2add(coeff[0], coeff[1], t3); // t3 = 2*X -+ fp2sqr_mont(t3, t3); // t3 = 4*X^2 -+ fp2sub(t3, t2, t3); // t3 = 4*X^2 - (X+Z)^2 - (X-Z)^2 -+ fp2add(t1, t3, t2); // t2 = 4*X^2 - (X-Z)^2 -+ fp2add(t3, t0, t3); // t3 = 4*X^2 - (X+Z)^2 -+ fp2add(t0, t3, t4); // t4 = 4*X^2 - (X+Z)^2 + (X-Z)^2 -+ fp2add(t4, t4, t4); // t4 = 2(4*X^2 - (X+Z)^2 + (X-Z)^2) -+ fp2add(t1, t4, t4); // t4 = 8*X^2 - (X+Z)^2 + 2*(X-Z)^2 -+ fp2mul_mont(t2, t4, A24minus); // A24minus = [4*X^2 - (X-Z)^2]*[8*X^2 - (X+Z)^2 + 2*(X-Z)^2] -+ fp2add(t1, t2, t4); // t4 = 4*X^2 + (X+Z)^2 - (X-Z)^2 -+ fp2add(t4, t4, t4); // t4 = 2(4*X^2 + (X+Z)^2 - (X-Z)^2) -+ fp2add(t0, t4, t4); // t4 = 8*X^2 + 2*(X+Z)^2 - (X-Z)^2 -+ fp2mul_mont(t3, t4, t4); // t4 = [4*X^2 - (X+Z)^2]*[8*X^2 + 2*(X+Z)^2 - (X-Z)^2] -+ fp2sub(t4, A24minus, t0); // t0 = [4*X^2 - (X+Z)^2]*[8*X^2 + 2*(X+Z)^2 - (X-Z)^2] - [4*X^2 - (X-Z)^2]*[8*X^2 - (X+Z)^2 + 2*(X-Z)^2] -+ fp2add(A24minus, t0, A24plus); // A24plus = 8*X^2 - (X+Z)^2 + 2*(X-Z)^2 -+} -+ -+ -+void eval_3_isog(point_proj_t Q, f2elm_t* coeff) -+{ // Computes the 3-isogeny R=phi(X:Z), given projective point (X3:Z3) of order 3 on a Montgomery curve and -+ // a point P with 2 coefficients in coeff (computed in the function get_3_isog()). -+ // Inputs: projective points P = (X3:Z3) and Q = (X:Z). -+ // Output: the projective point Q <- phi(Q) = (X3:Z3). -+ f2elm_t t0, t1, t2; -+ -+ fp2add(Q->X, Q->Z, t0); // t0 = X+Z -+ fp2sub(Q->X, Q->Z, t1); // t1 = X-Z -+ fp2mul_mont(t0, coeff[0], t0); // t0 = coeff0*(X+Z) -+ fp2mul_mont(t1, coeff[1], t1); // t1 = coeff1*(X-Z) -+ fp2add(t0, t1, t2); // t2 = coeff0*(X+Z) + coeff1*(X-Z) -+ fp2sub(t1, t0, t0); // t0 = coeff1*(X-Z) - coeff0*(X+Z) -+ fp2sqr_mont(t2, t2); // t2 = [coeff0*(X+Z) + coeff1*(X-Z)]^2 -+ fp2sqr_mont(t0, t0); // t0 = [coeff1*(X-Z) - coeff0*(X+Z)]^2 -+ fp2mul_mont(Q->X, t2, Q->X); // X3final = X*[coeff0*(X+Z) + coeff1*(X-Z)]^2 -+ fp2mul_mont(Q->Z, t0, Q->Z); // Z3final = Z*[coeff1*(X-Z) - coeff0*(X+Z)]^2 -+} -+ -+ -+void inv_3_way(f2elm_t z1, f2elm_t z2, f2elm_t z3) -+{ // 3-way simultaneous inversion -+ // Input: z1,z2,z3 -+ // Output: 1/z1,1/z2,1/z3 (override inputs). -+ f2elm_t t0, t1, t2, t3; -+ -+ fp2mul_mont(z1, z2, t0); // t0 = z1*z2 -+ fp2mul_mont(z3, t0, t1); // t1 = z1*z2*z3 -+ fp2inv_mont(t1); // t1 = 1/(z1*z2*z3) -+ fp2mul_mont(z3, t1, t2); // t2 = 1/(z1*z2) -+ fp2mul_mont(t2, z2, t3); // t3 = 1/z1 -+ fp2mul_mont(t2, z1, z2); // z2 = 1/z2 -+ fp2mul_mont(t0, t1, z3); // z3 = 1/z3 -+ fp2copy(t3, z1); // z1 = 1/z1 -+} -+ -+ -+void get_A(const f2elm_t xP, const f2elm_t xQ, const f2elm_t xR, f2elm_t A) -+{ // Given the x-coordinates of P, Q, and R, returns the value A corresponding to the Montgomery curve E_A: y^2=x^3+A*x^2+x such that R=Q-P on E_A. -+ // Input: the x-coordinates xP, xQ, and xR of the points P, Q and R. -+ // Output: the coefficient A corresponding to the curve E_A: y^2=x^3+A*x^2+x. -+ f2elm_t t0, t1, one = F2ELM_INIT; -+ -+ fpcopy((digit_t*)&kP503Params.Montgomery_one, one->c0); -+ fp2add(xP, xQ, t1); // t1 = xP+xQ -+ fp2mul_mont(xP, xQ, t0); // t0 = xP*xQ -+ fp2mul_mont(xR, t1, A); // A = xR*t1 -+ fp2add(t0, A, A); // A = A+t0 -+ fp2mul_mont(t0, xR, t0); // t0 = t0*xR -+ fp2sub(A, one, A); // A = A-1 -+ fp2add(t0, t0, t0); // t0 = t0+t0 -+ fp2add(t1, xR, t1); // t1 = t1+xR -+ fp2add(t0, t0, t0); // t0 = t0+t0 -+ fp2sqr_mont(A, A); // A = A^2 -+ fp2inv_mont(t0); // t0 = 1/t0 -+ fp2mul_mont(A, t0, A); // A = A*t0 -+ fp2sub(A, t1, A); // Afinal = A-t1 -+} -+ -+ -+void j_inv(const f2elm_t A, const f2elm_t C, f2elm_t jinv) -+{ // Computes the j-invariant of a Montgomery curve with projective constant. -+ // Input: A,C in GF(p^2). -+ // Output: j=256*(A^2-3*C^2)^3/(C^4*(A^2-4*C^2)), which is the j-invariant of the Montgomery curve B*y^2=x^3+(A/C)*x^2+x or (equivalently) j-invariant of B'*y^2=C*x^3+A*x^2+C*x. -+ f2elm_t t0, t1; -+ -+ fp2sqr_mont(A, jinv); // jinv = A^2 -+ fp2sqr_mont(C, t1); // t1 = C^2 -+ fp2add(t1, t1, t0); // t0 = t1+t1 -+ fp2sub(jinv, t0, t0); // t0 = jinv-t0 -+ fp2sub(t0, t1, t0); // t0 = t0-t1 -+ fp2sub(t0, t1, jinv); // jinv = t0-t1 -+ fp2sqr_mont(t1, t1); // t1 = t1^2 -+ fp2mul_mont(jinv, t1, jinv); // jinv = jinv*t1 -+ fp2add(t0, t0, t0); // t0 = t0+t0 -+ fp2add(t0, t0, t0); // t0 = t0+t0 -+ fp2sqr_mont(t0, t1); // t1 = t0^2 -+ fp2mul_mont(t0, t1, t0); // t0 = t0*t1 -+ fp2add(t0, t0, t0); // t0 = t0+t0 -+ fp2add(t0, t0, t0); // t0 = t0+t0 -+ fp2inv_mont(jinv); // jinv = 1/jinv -+ fp2mul_mont(jinv, t0, jinv); // jinv = t0*jinv -+} -+ -+ -+void xDBLADD(point_proj_t P, point_proj_t Q, const f2elm_t xPQ, const f2elm_t A24) -+{ // Simultaneous doubling and differential addition. -+ // Input: projective Montgomery points P=(XP:ZP) and Q=(XQ:ZQ) such that xP=XP/ZP and xQ=XQ/ZQ, affine difference xPQ=x(P-Q) and Montgomery curve constant A24=(A+2)/4. -+ // Output: projective Montgomery points P <- 2*P = (X2P:Z2P) such that x(2P)=X2P/Z2P, and Q <- P+Q = (XQP:ZQP) such that = x(Q+P)=XQP/ZQP. -+ f2elm_t t0, t1, t2; -+ -+ fp2add(P->X, P->Z, t0); // t0 = XP+ZP -+ fp2sub(P->X, P->Z, t1); // t1 = XP-ZP -+ fp2sqr_mont(t0, P->X); // XP = (XP+ZP)^2 -+ fp2sub(Q->X, Q->Z, t2); // t2 = XQ-ZQ -+ fp2correction(t2); -+ fp2add(Q->X, Q->Z, Q->X); // XQ = XQ+ZQ -+ fp2mul_mont(t0, t2, t0); // t0 = (XP+ZP)*(XQ-ZQ) -+ fp2sqr_mont(t1, P->Z); // ZP = (XP-ZP)^2 -+ fp2mul_mont(t1, Q->X, t1); // t1 = (XP-ZP)*(XQ+ZQ) -+ fp2sub(P->X, P->Z, t2); // t2 = (XP+ZP)^2-(XP-ZP)^2 -+ fp2mul_mont(P->X, P->Z, P->X); // XP = (XP+ZP)^2*(XP-ZP)^2 -+ fp2mul_mont(t2, A24, Q->X); // XQ = A24*[(XP+ZP)^2-(XP-ZP)^2] -+ fp2sub(t0, t1, Q->Z); // ZQ = (XP+ZP)*(XQ-ZQ)-(XP-ZP)*(XQ+ZQ) -+ fp2add(Q->X, P->Z, P->Z); // ZP = A24*[(XP+ZP)^2-(XP-ZP)^2]+(XP-ZP)^2 -+ fp2add(t0, t1, Q->X); // XQ = (XP+ZP)*(XQ-ZQ)+(XP-ZP)*(XQ+ZQ) -+ fp2mul_mont(P->Z, t2, P->Z); // ZP = [A24*[(XP+ZP)^2-(XP-ZP)^2]+(XP-ZP)^2]*[(XP+ZP)^2-(XP-ZP)^2] -+ fp2sqr_mont(Q->Z, Q->Z); // ZQ = [(XP+ZP)*(XQ-ZQ)-(XP-ZP)*(XQ+ZQ)]^2 -+ fp2sqr_mont(Q->X, Q->X); // XQ = [(XP+ZP)*(XQ-ZQ)+(XP-ZP)*(XQ+ZQ)]^2 -+ fp2mul_mont(Q->Z, xPQ, Q->Z); // ZQ = xPQ*[(XP+ZP)*(XQ-ZQ)-(XP-ZP)*(XQ+ZQ)]^2 -+} -diff --git a/third_party/sidh/src/fpx.c b/third_party/sidh/src/fpx.c -new file mode 100644 -index 000000000..4f933cbb5 ---- /dev/null -+++ b/third_party/sidh/src/fpx.c -@@ -0,0 +1,420 @@ -+/******************************************************************************************** -+* SIDH: an efficient supersingular isogeny cryptography library -+* -+* Abstract: core functions over GF(p) and GF(p^2) -+*********************************************************************************************/ -+ -+#include "sidh/def_p503.h" -+#include "P503_internal.h" -+#include "internal.h" -+ -+extern const struct params_t kP503Params; -+ -+inline void fpcopy(const felm_t a, felm_t c) -+{ // Copy a field element, c = a. -+ unsigned int i; -+ -+ for (i = 0; i < NWORDS_FIELD; i++) -+ c[i] = a[i]; -+} -+ -+ -+inline void fpzero(felm_t a) -+{ // Zero a field element, a = 0. -+ unsigned int i; -+ -+ for (i = 0; i < NWORDS_FIELD; i++) -+ a[i] = 0; -+} -+ -+ -+void to_mont(const felm_t a, felm_t mc) -+{ // Conversion to Montgomery representation, -+ // mc = a*R^2*R^(-1) mod p = a*R mod p, where a in [0, p-1]. -+ // The Montgomery constant R^2 mod p is the global value "Montgomery_R2". -+ -+ fpmul_mont(a, (digit_t*)&kP503Params.Montgomery_R2, mc); -+} -+ -+ -+void from_mont(const felm_t ma, felm_t c) -+{ // Conversion from Montgomery representation to standard representation, -+ // c = ma*R^(-1) mod p = a mod p, where ma in [0, p-1]. -+ digit_t one[NWORDS_FIELD] = {0}; -+ -+ one[0] = 1; -+ fpmul_mont(ma, one, c); -+ fpcorrection(c); -+} -+ -+ -+void copy_words(const digit_t* a, digit_t* c, const unsigned int nwords) -+{ // Copy wordsize digits, c = a, where lng(a) = nwords. -+ unsigned int i; -+ -+ for (i = 0; i < nwords; i++) { -+ c[i] = a[i]; -+ } -+} -+ -+ -+void fpmul_mont(const felm_t ma, const felm_t mb, felm_t mc) -+{ // Multiprecision multiplication, c = a*b mod p. -+ dfelm_t temp = {0}; -+ -+ mp_mul(ma, mb, temp, NWORDS_FIELD); -+ rdc_mont(temp, mc); -+} -+ -+ -+void fpsqr_mont(const felm_t ma, felm_t mc) -+{ // Multiprecision squaring, c = a^2 mod p. -+ dfelm_t temp = {0}; -+ -+ mp_mul(ma, ma, temp, NWORDS_FIELD); -+ rdc_mont(temp, mc); -+} -+ -+ -+void fpinv_mont(felm_t a) -+{ // Field inversion using Montgomery arithmetic, a = a^(-1)*R mod p. -+ felm_t tt; -+ -+ fpcopy(a, tt); -+ fpinv_chain_mont(tt); -+ fpsqr_mont(tt, tt); -+ fpsqr_mont(tt, tt); -+ fpmul_mont(a, tt, a); -+} -+ -+ -+void fp2copy(const f2elm_t a, f2elm_t c) -+{ // Copy a GF(p^2) element, c = a. -+ fpcopy(a->c0, c->c0); -+ fpcopy(a->c1, c->c1); -+} -+ -+ -+void fp2zero(f2elm_t a) -+{ // Zero a GF(p^2) element, a = 0. -+ fpzero(a->c0); -+ fpzero(a->c1); -+} -+ -+ -+void fp2neg(f2elm_t a) -+{ // GF(p^2) negation, a = -a in GF(p^2). -+ fpneg(a->c0); -+ fpneg(a->c1); -+} -+ -+inline void fp2add(const f2elm_t a, const f2elm_t b, f2elm_t c) -+{ // GF(p^2) addition, c = a+b in GF(p^2). -+ fpadd(a->c0, b->c0, c->c0); -+ fpadd(a->c1, b->c1, c->c1); -+} -+ -+inline void fp2sub(const f2elm_t a, const f2elm_t b, f2elm_t c) -+{ // GF(p^2) subtraction, c = a-b in GF(p^2). -+ fpsub(a->c0, b->c0, c->c0); -+ fpsub(a->c1, b->c1, c->c1); -+} -+ -+ -+void fp2div2(const f2elm_t a, f2elm_t c) -+{ // GF(p^2) division by two, c = a/2 in GF(p^2). -+ fpdiv2(a->c0, c->c0); -+ fpdiv2(a->c1, c->c1); -+} -+ -+ -+void fp2correction(f2elm_t a) -+{ // Modular correction, a = a in GF(p^2). -+ fpcorrection(a->c0); -+ fpcorrection(a->c1); -+} -+ -+ -+inline static void mp_addfast(const digit_t* a, const digit_t* b, digit_t* c) -+{ // Multiprecision addition, c = a+b. -+#if defined(OPENSSL_NO_ASM) -+ mp_add(a, b, c, NWORDS_FIELD); -+#else -+ mp_add_asm(a, b, c); -+ -+#endif -+} -+ -+ -+void fp2sqr_mont(const f2elm_t a, f2elm_t c) -+{ // GF(p^2) squaring using Montgomery arithmetic, c = a^2 in GF(p^2). -+ // Inputs: a = a0+a1*i, where a0, a1 are in [0, 2*p-1] -+ // Output: c = c0+c1*i, where c0, c1 are in [0, 2*p-1] -+ felm_t t1, t2, t3; -+ -+ mp_addfast(a->c0, a->c1, t1); // t1 = a0+a1 -+ fpsub(a->c0, a->c1, t2); // t2 = a0-a1 -+ mp_addfast(a->c0, a->c0, t3); // t3 = 2a0 -+ fpmul_mont(t1, t2, c->c0); // c0 = (a0+a1)(a0-a1) -+ fpmul_mont(t3, a->c1, c->c1); // c1 = 2a0*a1 -+} -+ -+ -+inline unsigned int mp_sub(const digit_t* a, const digit_t* b, digit_t* c, const unsigned int nwords) -+{ // Multiprecision subtraction, c = a-b, where lng(a) = lng(b) = nwords. Returns the borrow bit. -+ unsigned int i, borrow = 0; -+ -+ for (i = 0; i < nwords; i++) { -+ SUBC(borrow, a[i], b[i], borrow, c[i]); -+ } -+ -+ return borrow; -+} -+ -+ -+inline static digit_t mp_subfast(const digit_t* a, const digit_t* b, digit_t* c) -+{ // Multiprecision subtraction, c = a-b, where lng(a) = lng(b) = 2*NWORDS_FIELD. -+ // If c < 0 then returns mask = 0xFF..F, else mask = 0x00..0 -+#if defined(OPENSSL_NO_ASM) -+ -+ return (0 - (digit_t)mp_sub(a, b, c, 2*NWORDS_FIELD)); -+ -+#else -+ -+ return mp_subx2_asm(a, b, c); -+ -+#endif -+} -+ -+ -+inline static void mp_dblsubfast(const digit_t* a, const digit_t* b, digit_t* c) -+{ // Multiprecision subtraction, c = c-a-b, where lng(a) = lng(b) = 2*NWORDS_FIELD. -+ // Inputs should be s.t. c > a and c > b -+#if defined(OPENSSL_NO_ASM) -+ -+ mp_sub(c, a, c, 2*NWORDS_FIELD); -+ mp_sub(c, b, c, 2*NWORDS_FIELD); -+ -+#else -+ -+ mp_dblsubx2_asm(a, b, c); -+ -+#endif -+} -+ -+ -+void fp2mul_mont(const f2elm_t a, const f2elm_t b, f2elm_t c) -+{ // GF(p^2) multiplication using Montgomery arithmetic, c = a*b in GF(p^2). -+ // Inputs: a = a0+a1*i and b = b0+b1*i, where a0, a1, b0, b1 are in [0, 2*p-1] -+ // Output: c = c0+c1*i, where c0, c1 are in [0, 2*p-1] -+ felm_t t1, t2; -+ dfelm_t tt1, tt2, tt3; -+ digit_t mask; -+ unsigned int i; -+ -+ mp_addfast(a->c0, a->c1, t1); // t1 = a0+a1 -+ mp_addfast(b->c0, b->c1, t2); // t2 = b0+b1 -+ mp_mul(a->c0, b->c0, tt1, NWORDS_FIELD); // tt1 = a0*b0 -+ mp_mul(a->c1, b->c1, tt2, NWORDS_FIELD); // tt2 = a1*b1 -+ mp_mul(t1, t2, tt3, NWORDS_FIELD); // tt3 = (a0+a1)*(b0+b1) -+ mp_dblsubfast(tt1, tt2, tt3); // tt3 = (a0+a1)*(b0+b1) - a0*b0 - a1*b1 -+ mask = mp_subfast(tt1, tt2, tt1); // tt1 = a0*b0 - a1*b1. If tt1 < 0 then mask = 0xFF..F, else if tt1 >= 0 then mask = 0x00..0 -+ -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ t1[i] = ((digit_t*)kP503Params.prime)[i] & mask; -+ } -+ -+ rdc_mont(tt3, c->c1); // c[1] = (a0+a1)*(b0+b1) - a0*b0 - a1*b1 -+ mp_addfast((digit_t*)&tt1[NWORDS_FIELD], t1, (digit_t*)&tt1[NWORDS_FIELD]); -+ rdc_mont(tt1, c->c0); // c[0] = a0*b0 - a1*b1 -+} -+ -+ -+void fpinv_chain_mont(felm_t a) -+{ // Chain to compute a^(p-3)/4 using Montgomery arithmetic. -+ unsigned int i, j; -+ felm_t t[15], tt; -+ -+ // Precomputed table -+ fpsqr_mont(a, tt); -+ fpmul_mont(a, tt, t[0]); -+ for (i = 0; i <= 13; i++) fpmul_mont(t[i], tt, t[i+1]); -+ -+ fpcopy(a, tt); -+ for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(a, tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[8], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[6], tt, tt); -+ for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[9], tt, tt); -+ for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[0], tt, tt); -+ for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(a, tt, tt); -+ for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[6], tt, tt); -+ for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[2], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[8], tt, tt); -+ for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(a, tt, tt); -+ for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[10], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[0], tt, tt); -+ for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[10], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[10], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[5], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[2], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[6], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[3], tt, tt); -+ for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[5], tt, tt); -+ for (i = 0; i < 12; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[12], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[8], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[6], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[12], tt, tt); -+ for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[11], tt, tt); -+ for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[6], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[5], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[14], tt, tt); -+ for (i = 0; i < 7; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[14], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[5], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[6], tt, tt); -+ for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[8], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(a, tt, tt); -+ for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[4], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[6], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[5], tt, tt); -+ for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[7], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(a, tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[0], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[11], tt, tt); -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[13], tt, tt); -+ for (i = 0; i < 8; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[1], tt, tt); -+ for (i = 0; i < 6; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[10], tt, tt); -+ for (j = 0; j < 49; j++) { -+ for (i = 0; i < 5; i++) fpsqr_mont(tt, tt); -+ fpmul_mont(t[14], tt, tt); -+ } -+ fpcopy(tt, a); -+} -+ -+ -+void fp2inv_mont(f2elm_t a) -+{// GF(p^2) inversion using Montgomery arithmetic, a = (a0-i*a1)/(a0^2+a1^2). -+ f2elm_t t1; -+ -+ fpsqr_mont(a->c0, t1->c0); // t10 = a0^2 -+ fpsqr_mont(a->c1, t1->c1); // t11 = a1^2 -+ fpadd(t1->c0, t1->c1, t1->c0); // t10 = a0^2+a1^2 -+ fpinv_mont(t1->c0); // t10 = (a0^2+a1^2)^-1 -+ fpneg(a->c1); // a = a0-i*a1 -+ fpmul_mont(a->c0, t1->c0, a->c0); -+ fpmul_mont(a->c1, t1->c0, a->c1); // a = (a0-i*a1)*(a0^2+a1^2)^-1 -+} -+ -+ -+void to_fp2mont(const f2elm_t a, f2elm_t mc) -+{ // Conversion of a GF(p^2) element to Montgomery representation, -+ // mc_i = a_i*R^2*R^(-1) = a_i*R in GF(p^2). -+ -+ to_mont(a->c0, mc->c0); -+ to_mont(a->c1, mc->c1); -+} -+ -+ -+void from_fp2mont(const f2elm_t ma, f2elm_t c) -+{ // Conversion of a GF(p^2) element from Montgomery representation to standard representation, -+ // c_i = ma_i*R^(-1) = a_i in GF(p^2). -+ -+ from_mont(ma->c0, c->c0); -+ from_mont(ma->c1, c->c1); -+} -+ -+ -+inline unsigned int mp_add(const digit_t* a, const digit_t* b, digit_t* c, const unsigned int nwords) -+{ // Multiprecision addition, c = a+b, where lng(a) = lng(b) = nwords. Returns the carry bit. -+ unsigned int i, carry = 0; -+ -+ for (i = 0; i < nwords; i++) { -+ ADDC(carry, a[i], b[i], carry, c[i]); -+ } -+ -+ return carry; -+} -+ -+ -+void mp_shiftleft(digit_t* x, unsigned int shift, const unsigned int nwords) -+{ -+ unsigned int i, j = 0; -+ -+ while (shift > RADIX) { -+ j += 1; -+ shift -= RADIX; -+ } -+ -+ for (i = 0; i < nwords-j; i++) -+ x[nwords-1-i] = x[nwords-1-i-j]; -+ for (i = nwords-j; i < nwords; i++) -+ x[nwords-1-i] = 0; -+ if (shift != 0) { -+ for (j = nwords-1; j > 0; j--) -+ SHIFTL(x[j], x[j-1], shift, x[j], RADIX); -+ x[0] <<= shift; -+ } -+} -+ -+ -+void mp_shiftr1(digit_t* x, const unsigned int nwords) -+{ // Multiprecision right shift by one. -+ unsigned int i; -+ -+ for (i = 0; i < nwords-1; i++) { -+ SHIFTR(x[i+1], x[i], 1, x[i], RADIX); -+ } -+ x[nwords-1] >>= 1; -+} -+ -+ -+void mp_shiftl1(digit_t* x, const unsigned int nwords) -+{ // Multiprecision left shift by one. -+ int i; -+ -+ for (i = nwords-1; i > 0; i--) { -+ SHIFTL(x[i], x[i-1], 1, x[i], RADIX); -+ } -+ x[0] <<= 1; -+} -diff --git a/third_party/sidh/src/generic/fp_generic.c b/third_party/sidh/src/generic/fp_generic.c -new file mode 100644 -index 000000000..325053f1c ---- /dev/null -+++ b/third_party/sidh/src/generic/fp_generic.c -@@ -0,0 +1,222 @@ -+/******************************************************************************************** -+* SIDH: an efficient supersingular isogeny cryptography library -+* -+* Abstract: portable modular arithmetic for P503 -+*********************************************************************************************/ -+ -+#include "../internal.h" -+#include "../P503_internal.h" -+ -+ -+// Global constants -+extern const struct params_t kP503Params; -+ -+inline void fpadd503(const digit_t* a, const digit_t* b, digit_t* c) -+{ // Modular addition, c = a+b mod p503. -+ // Inputs: a, b in [0, 2*p503-1] -+ // Output: c in [0, 2*p503-1] -+ unsigned int i, carry = 0; -+ digit_t mask; -+ -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ ADDC(carry, a[i], b[i], carry, c[i]); -+ } -+ -+ carry = 0; -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ SUBC(carry, c[i], ((digit_t*)kP503Params.primeX2)[i], carry, c[i]); -+ } -+ mask = 0 - (digit_t)carry; -+ -+ carry = 0; -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ ADDC(carry, c[i], ((digit_t*)kP503Params.primeX2)[i] & mask, carry, c[i]); -+ } -+} -+ -+ -+inline void fpsub503(const digit_t* a, const digit_t* b, digit_t* c) -+{ // Modular subtraction, c = a-b mod p503. -+ // Inputs: a, b in [0, 2*p503-1] -+ // Output: c in [0, 2*p503-1] -+ unsigned int i, borrow = 0; -+ digit_t mask; -+ -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ SUBC(borrow, a[i], b[i], borrow, c[i]); -+ } -+ mask = 0 - (digit_t)borrow; -+ -+ borrow = 0; -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ ADDC(borrow, c[i], ((digit_t*)kP503Params.primeX2)[i] & mask, borrow, c[i]); -+ } -+} -+ -+ -+inline void fpneg503(digit_t* a) -+{ // Modular negation, a = -a mod p503. -+ // Input/output: a in [0, 2*p503-1] -+ unsigned int i, borrow = 0; -+ -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ SUBC(borrow, ((digit_t*)kP503Params.primeX2)[i], a[i], borrow, a[i]); -+ } -+} -+ -+ -+void fpdiv2_503(const digit_t* a, digit_t* c) -+{ // Modular division by two, c = a/2 mod p503. -+ // Input : a in [0, 2*p503-1] -+ // Output: c in [0, 2*p503-1] -+ unsigned int i, carry = 0; -+ digit_t mask; -+ -+ mask = 0 - (digit_t)(a[0] & 1); // If a is odd compute a+p503 -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ ADDC(carry, a[i], ((digit_t*)kP503Params.prime)[i] & mask, carry, c[i]); -+ } -+ -+ mp_shiftr1(c, NWORDS_FIELD); -+} -+ -+ -+void fpcorrection503(digit_t* a) -+{ // Modular correction to reduce field element a in [0, 2*p503-1] to [0, p503-1]. -+ unsigned int i, borrow = 0; -+ digit_t mask; -+ -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ SUBC(borrow, a[i], ((digit_t*)kP503Params.prime)[i], borrow, a[i]); -+ } -+ mask = 0 - (digit_t)borrow; -+ -+ borrow = 0; -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ ADDC(borrow, a[i], ((digit_t*)kP503Params.prime)[i] & mask, borrow, a[i]); -+ } -+} -+ -+ -+void digit_x_digit(const digit_t a, const digit_t b, digit_t* c) -+{ // Digit multiplication, digit * digit -> 2-digit result -+ register digit_t al, ah, bl, bh, temp; -+ digit_t albl, albh, ahbl, ahbh, res1, res2, res3, carry; -+ digit_t mask_low = (digit_t)(-1) >> (sizeof(digit_t)*4), mask_high = (digit_t)(-1) << (sizeof(digit_t)*4); -+ -+ al = a & mask_low; // Low part -+ ah = a >> (sizeof(digit_t) * 4); // High part -+ bl = b & mask_low; -+ bh = b >> (sizeof(digit_t) * 4); -+ -+ albl = al*bl; -+ albh = al*bh; -+ ahbl = ah*bl; -+ ahbh = ah*bh; -+ c[0] = albl & mask_low; // C00 -+ -+ res1 = albl >> (sizeof(digit_t) * 4); -+ res2 = ahbl & mask_low; -+ res3 = albh & mask_low; -+ temp = res1 + res2 + res3; -+ carry = temp >> (sizeof(digit_t) * 4); -+ c[0] ^= temp << (sizeof(digit_t) * 4); // C01 -+ -+ res1 = ahbl >> (sizeof(digit_t) * 4); -+ res2 = albh >> (sizeof(digit_t) * 4); -+ res3 = ahbh & mask_low; -+ temp = res1 + res2 + res3 + carry; -+ c[1] = temp & mask_low; // C10 -+ carry = temp & mask_high; -+ c[1] ^= (ahbh & mask_high) + carry; // C11 -+} -+ -+ -+void mp_mul(const digit_t* a, const digit_t* b, digit_t* c, const unsigned int nwords) -+{ // Multiprecision comba multiply, c = a*b, where lng(a) = lng(b) = nwords. -+ unsigned int i, j; -+ digit_t t = 0, u = 0, v = 0, UV[2]; -+ unsigned int carry = 0; -+ -+ for (i = 0; i < nwords; i++) { -+ for (j = 0; j <= i; j++) { -+ MUL(a[j], b[i-j], UV+1, UV[0]); -+ ADDC(0, UV[0], v, carry, v); -+ ADDC(carry, UV[1], u, carry, u); -+ t += carry; -+ } -+ c[i] = v; -+ v = u; -+ u = t; -+ t = 0; -+ } -+ -+ for (i = nwords; i < 2*nwords-1; i++) { -+ for (j = i-nwords+1; j < nwords; j++) { -+ MUL(a[j], b[i-j], UV+1, UV[0]); -+ ADDC(0, UV[0], v, carry, v); -+ ADDC(carry, UV[1], u, carry, u); -+ t += carry; -+ } -+ c[i] = v; -+ v = u; -+ u = t; -+ t = 0; -+ } -+ c[2*nwords-1] = v; -+} -+ -+ -+void rdc_mont(const digit_t* ma, digit_t* mc) -+{ // Efficient Montgomery reduction using comba and exploiting the special form of the prime p503. -+ // mc = ma*R^-1 mod p503x2, where R = 2^512. -+ // If ma < 2^512*p503, the output mc is in the range [0, 2*p503-1]. -+ // ma is assumed to be in Montgomery representation. -+ unsigned int i, j, carry, count = p503_ZERO_WORDS; -+ digit_t UV[2], t = 0, u = 0, v = 0; -+ -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ mc[i] = 0; -+ } -+ -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ for (j = 0; j < i; j++) { -+ if (j < (i-p503_ZERO_WORDS+1)) { -+ MUL(mc[j], ((digit_t*)kP503Params.primeP1)[i-j], UV+1, UV[0]); -+ ADDC(0, UV[0], v, carry, v); -+ ADDC(carry, UV[1], u, carry, u); -+ t += carry; -+ } -+ } -+ ADDC(0, v, ma[i], carry, v); -+ ADDC(carry, u, 0, carry, u); -+ t += carry; -+ mc[i] = v; -+ v = u; -+ u = t; -+ t = 0; -+ } -+ -+ for (i = NWORDS_FIELD; i < 2*NWORDS_FIELD-1; i++) { -+ if (count > 0) { -+ count -= 1; -+ } -+ for (j = i-NWORDS_FIELD+1; j < NWORDS_FIELD; j++) { -+ if (j < (NWORDS_FIELD-count)) { -+ MUL(mc[j], ((digit_t*)kP503Params.primeP1)[i-j], UV+1, UV[0]); -+ ADDC(0, UV[0], v, carry, v); -+ ADDC(carry, UV[1], u, carry, u); -+ t += carry; -+ } -+ } -+ ADDC(0, v, ma[i], carry, v); -+ ADDC(carry, u, 0, carry, u); -+ t += carry; -+ mc[i-NWORDS_FIELD] = v; -+ v = u; -+ u = t; -+ t = 0; -+ } -+ ADDC(0, v, ma[2*NWORDS_FIELD-1], carry, v); -+ mc[NWORDS_FIELD-1] = v; -+} -\ No newline at end of file -diff --git a/third_party/sidh/src/internal.h b/third_party/sidh/src/internal.h -new file mode 100644 -index 000000000..8a32b465c ---- /dev/null -+++ b/third_party/sidh/src/internal.h -@@ -0,0 +1,96 @@ -+#ifndef INTERNAL_H_ -+#define INTERNAL_H_ -+ -+#include "sidh/def_p503.h" -+ -+/********************** Macros for platform-dependent operations **********************/ -+ -+#if defined(OPENSSL_NO_ASM) -+ -+/********************** Constant-time unsigned comparisons ***********************/ -+ -+// The following functions return 1 (TRUE) if condition is true, 0 (FALSE) otherwise -+ -+static inline unsigned int is_digit_nonzero_ct(digit_t x) -+{ // Is x != 0? -+ return (unsigned int)((x | (0-x)) >> (RADIX-1)); -+} -+ -+static inline unsigned int is_digit_zero_ct(digit_t x) -+{ // Is x = 0? -+ return (unsigned int)(1 ^ is_digit_nonzero_ct(x)); -+} -+ -+static inline unsigned int is_digit_lessthan_ct(digit_t x, digit_t y) -+{ // Is x < y? -+ return (unsigned int)((x ^ ((x ^ y) | ((x - y) ^ y))) >> (RADIX-1)); -+} -+ -+// Digit multiplication -+#define MUL(multiplier, multiplicand, hi, lo) \ -+ digit_x_digit((multiplier), (multiplicand), &(lo)); -+ -+// Digit addition with carry -+#define ADDC(carryIn, addend1, addend2, carryOut, sumOut) \ -+ { digit_t tempReg = (addend1) + (digit_t)(carryIn); \ -+ (sumOut) = (addend2) + tempReg; \ -+ (carryOut) = (is_digit_lessthan_ct(tempReg, (digit_t)(carryIn)) | is_digit_lessthan_ct((sumOut), tempReg)); } -+ -+// Digit subtraction with borrow -+#define SUBC(borrowIn, minuend, subtrahend, borrowOut, differenceOut) \ -+ { digit_t tempReg = (minuend) - (subtrahend); \ -+ unsigned int borrowReg = (is_digit_lessthan_ct((minuend), (subtrahend)) | ((borrowIn) & is_digit_zero_ct(tempReg))); \ -+ (differenceOut) = tempReg - (digit_t)(borrowIn); \ -+ (borrowOut) = borrowReg; } -+ -+// Shift right with flexible datatype -+#define SHIFTR(highIn, lowIn, shift, shiftOut, DigitSize) \ -+ (shiftOut) = ((lowIn) >> (shift)) ^ ((highIn) << (DigitSize - (shift))); -+ -+// Shift left with flexible datatype -+#define SHIFTL(highIn, lowIn, shift, shiftOut, DigitSize) \ -+ (shiftOut) = ((highIn) << (shift)) ^ ((lowIn) >> (DigitSize - (shift))); -+ -+// 64x64-bit multiplication -+#define MUL128(multiplier, multiplicand, product) \ -+ mp_mul((digit_t*)&(multiplier), (digit_t*)&(multiplicand), (digit_t*)&(product), NWORDS_FIELD/2); -+ -+// 128-bit addition, inputs < 2^127 -+#define ADD128(addend1, addend2, addition) \ -+ mp_add((digit_t*)(addend1), (digit_t*)(addend2), (digit_t*)(addition), NWORDS_FIELD); -+ -+// 128-bit addition with output carry -+#define ADC128(addend1, addend2, carry, addition) \ -+ (carry) = mp_add((digit_t*)(addend1), (digit_t*)(addend2), (digit_t*)(addition), NWORDS_FIELD); -+ -+#else -+ -+// Digit multiplication -+#define MUL(multiplier, multiplicand, hi, lo) \ -+ { uint128_t tempReg = (uint128_t)(multiplier) * (uint128_t)(multiplicand); \ -+ *(hi) = (digit_t)(tempReg >> RADIX); \ -+ (lo) = (digit_t)tempReg; } -+ -+// Digit addition with carry -+#define ADDC(carryIn, addend1, addend2, carryOut, sumOut) \ -+ { uint128_t tempReg = (uint128_t)(addend1) + (uint128_t)(addend2) + (uint128_t)(carryIn); \ -+ (carryOut) = (digit_t)(tempReg >> RADIX); \ -+ (sumOut) = (digit_t)tempReg; } -+ -+// Digit subtraction with borrow -+#define SUBC(borrowIn, minuend, subtrahend, borrowOut, differenceOut) \ -+ { uint128_t tempReg = (uint128_t)(minuend) - (uint128_t)(subtrahend) - (uint128_t)(borrowIn); \ -+ (borrowOut) = (digit_t)(tempReg >> (sizeof(uint128_t)*8 - 1)); \ -+ (differenceOut) = (digit_t)tempReg; } -+ -+// Digit shift right -+#define SHIFTR(highIn, lowIn, shift, shiftOut, DigitSize) \ -+ (shiftOut) = ((lowIn) >> (shift)) ^ ((highIn) << (RADIX - (shift))); -+ -+// Digit shift left -+#define SHIFTL(highIn, lowIn, shift, shiftOut, DigitSize) \ -+ (shiftOut) = ((highIn) << (shift)) ^ ((lowIn) >> (RADIX - (shift))); -+ -+#endif -+ -+#endif // INTERNAL_H_ -diff --git a/third_party/sidh/src/sidh.c b/third_party/sidh/src/sidh.c -new file mode 100644 -index 000000000..fdbd87e28 ---- /dev/null -+++ b/third_party/sidh/src/sidh.c -@@ -0,0 +1,410 @@ -+/******************************************************************************************** -+* SIDH: an efficient supersingular isogeny cryptography library -+* -+* Abstract: ephemeral supersingular isogeny Diffie-Hellman key exchange (SIDH) -+*********************************************************************************************/ -+ -+#include "openssl/bn.h" -+#include "openssl/base.h" -+ -+#include "sidh/def_p503.h" -+#include "P503_internal.h" -+ -+extern const struct params_t kP503Params; -+ -+// Returns private key bit size for type A (IsInitiator=true) or B (IsInitiator=false) type. -+static inline size_t PrvKeyBitSz(int IsInitiator) { -+ return IsInitiator?SIDHp503_PRV_A_BITSZ:SIDHp503_PRV_B_BITSZ; -+} -+ -+// Swap points. -+// If option = 0 then P <- P and Q <- Q, else if option = 0xFF...FF then P <- Q and Q <- P -+#if !defined(OPENSSL_X86_64) || defined(OPENSSL_NO_ASM) -+static void cswap(point_proj_t P, point_proj_t Q, const digit_t option) -+{ -+ digit_t temp; -+ unsigned int i; -+ -+ for (i = 0; i < NWORDS_FIELD; i++) { -+ temp = option & (P->X->c0[i] ^ Q->X->c0[i]); -+ P->X->c0[i] = temp ^ P->X->c0[i]; -+ Q->X->c0[i] = temp ^ Q->X->c0[i]; -+ temp = option & (P->Z->c0[i] ^ Q->Z->c0[i]); -+ P->Z->c0[i] = temp ^ P->Z->c0[i]; -+ Q->Z->c0[i] = temp ^ Q->Z->c0[i]; -+ temp = option & (P->X->c1[i] ^ Q->X->c1[i]); -+ P->X->c1[i] = temp ^ P->X->c1[i]; -+ Q->X->c1[i] = temp ^ Q->X->c1[i]; -+ temp = option & (P->Z->c1[i] ^ Q->Z->c1[i]); -+ P->Z->c1[i] = temp ^ P->Z->c1[i]; -+ Q->Z->c1[i] = temp ^ Q->Z->c1[i]; -+ } -+} -+#endif -+ -+// Swap points. -+// If option = 0 then P <- P and Q <- Q, else if option = 0xFF...FF then P <- Q and Q <- P -+static inline void fp2cswap(point_proj_t P, point_proj_t Q, const digit_t option) -+{ -+#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) -+ cswap_asm(P, Q, option); -+#else -+ cswap(P, Q, option); -+#endif -+} -+ -+static void LADDER3PT(const f2elm_t xP, const f2elm_t xQ, const f2elm_t xPQ, const digit_t* m, const unsigned int AliceOrBob, point_proj_t R, const f2elm_t A) -+{ -+ point_proj_t R0 = POINT_PROJ_INIT, R2 = POINT_PROJ_INIT; -+ f2elm_t A24 = F2ELM_INIT; -+ digit_t mask; -+ int i, nbits, bit, swap, prevbit = 0; -+ -+ if (AliceOrBob == ALICE) { -+ nbits = OALICE_BITS; -+ } else { -+ nbits = OBOB_BITS; -+ } -+ -+ // Initializing constant -+ fpcopy((digit_t*)&kP503Params.Montgomery_one, A24->c0); -+ fp2add(A24, A24, A24); -+ fp2add(A, A24, A24); -+ fp2div2(A24, A24); -+ fp2div2(A24, A24); // A24 = (A+2)/4 -+ -+ // Initializing points -+ fp2copy(xQ, R0->X); -+ fpcopy((digit_t*)&kP503Params.Montgomery_one, (digit_t*)R0->Z); -+ fp2copy(xPQ, R2->X); -+ fpcopy((digit_t*)&kP503Params.Montgomery_one, (digit_t*)R2->Z); -+ fp2copy(xP, R->X); -+ fpcopy((digit_t*)&kP503Params.Montgomery_one, (digit_t*)R->Z); -+ fpzero((digit_t*)(R->Z)->c1); -+ -+ // Main loop -+ for (i = 0; i < nbits; i++) { -+ bit = (m[i >> LOG2RADIX] >> (i & (RADIX-1))) & 1; -+ swap = bit ^ prevbit; -+ prevbit = bit; -+ mask = 0 - (digit_t)swap; -+ -+ fp2cswap(R, R2, mask); -+ xDBLADD(R0, R2, R->X, A24); -+ fp2mul_mont(R2->X, R->Z, R2->X); -+ } -+} -+ -+// Initialization of basis points -+static void init_basis(digit_t *gen, f2elm_t XP, f2elm_t XQ, f2elm_t XR) -+{ -+ -+ fpcopy(gen, XP->c0); -+ fpcopy(gen + NWORDS_FIELD, XP->c1); -+ fpcopy(gen + 2*NWORDS_FIELD, XQ->c0); -+ fpzero(XQ->c1); -+ fpcopy(gen + 3*NWORDS_FIELD, XR->c0); -+ fpcopy(gen + 4*NWORDS_FIELD, XR->c1); -+} -+ -+// Conversion of GF(p^2) element from Montgomery to standard representation, and encoding by removing leading 0 bytes -+static void fp2_encode(const f2elm_t x, unsigned char *enc) -+{ -+ unsigned int i; -+ f2elm_t t; -+ -+ from_fp2mont(x, t); -+ for (i = 0; i < FP2_ENCODED_BYTES / 2; i++) { -+ enc[i] = ((unsigned char*)t)[i]; -+ enc[i + FP2_ENCODED_BYTES / 2] = ((unsigned char*)t)[i + MAXBITS_FIELD / 8]; -+ } -+} -+ -+// Parse byte sequence back into GF(p^2) element, and conversion to Montgomery representation -+static void fp2_decode(const unsigned char *enc, f2elm_t x) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < 2*(MAXBITS_FIELD / 8); i++) ((unsigned char *)x)[i] = 0; -+ for (i = 0; i < FP2_ENCODED_BYTES / 2; i++) { -+ ((unsigned char*)x)[i] = enc[i]; -+ ((unsigned char*)x)[i + MAXBITS_FIELD / 8] = enc[i + FP2_ENCODED_BYTES / 2]; -+ } -+ to_fp2mont(x, x); -+} -+ -+int EphemeralKeyGeneration_A(const unsigned char* PrivateKeyA, unsigned char* PublicKeyA) -+{ -+ point_proj_t R, phiP = POINT_PROJ_INIT, phiQ = POINT_PROJ_INIT, phiR = POINT_PROJ_INIT, pts[MAX_INT_POINTS_ALICE]; -+ f2elm_t XPA, XQA, XRA, coeff[3], A24plus = F2ELM_INIT, C24 = F2ELM_INIT, A = F2ELM_INIT; -+ unsigned int i, row, m, index = 0, pts_index[MAX_INT_POINTS_ALICE], npts = 0, ii = 0; -+ -+ // Initialize basis points -+ init_basis((digit_t*)kP503Params.A_gen, XPA, XQA, XRA); -+ init_basis((digit_t*)kP503Params.B_gen, phiP->X, phiQ->X, phiR->X); -+ fpcopy((digit_t*)&kP503Params.Montgomery_one, (phiP->Z)->c0); -+ fpcopy((digit_t*)&kP503Params.Montgomery_one, (phiQ->Z)->c0); -+ fpcopy((digit_t*)&kP503Params.Montgomery_one, (phiR->Z)->c0); -+ -+ // Initialize constants -+ fpcopy((digit_t*)&kP503Params.Montgomery_one, A24plus->c0); -+ fp2add(A24plus, A24plus, C24); -+ -+ // Retrieve kernel point -+ LADDER3PT(XPA, XQA, XRA, (digit_t*)PrivateKeyA, ALICE, R, A); -+ -+ // Traverse tree -+ index = 0; -+ for (row = 1; row < MAX_Alice; row++) { -+ while (index < MAX_Alice-row) { -+ fp2copy(R->X, pts[npts]->X); -+ fp2copy(R->Z, pts[npts]->Z); -+ pts_index[npts++] = index; -+ m = kP503Params.strat_Alice[ii++]; -+ xDBLe(R, R, A24plus, C24, (int)(2*m)); -+ index += m; -+ } -+ get_4_isog(R, A24plus, C24, coeff); -+ -+ for (i = 0; i < npts; i++) { -+ eval_4_isog(pts[i], coeff); -+ } -+ eval_4_isog(phiP, coeff); -+ eval_4_isog(phiQ, coeff); -+ eval_4_isog(phiR, coeff); -+ -+ fp2copy(pts[npts-1]->X, R->X); -+ fp2copy(pts[npts-1]->Z, R->Z); -+ index = pts_index[npts-1]; -+ npts -= 1; -+ } -+ -+ get_4_isog(R, A24plus, C24, coeff); -+ eval_4_isog(phiP, coeff); -+ eval_4_isog(phiQ, coeff); -+ eval_4_isog(phiR, coeff); -+ -+ inv_3_way(phiP->Z, phiQ->Z, phiR->Z); -+ fp2mul_mont(phiP->X, phiP->Z, phiP->X); -+ fp2mul_mont(phiQ->X, phiQ->Z, phiQ->X); -+ fp2mul_mont(phiR->X, phiR->Z, phiR->X); -+ -+ // Format public key -+ fp2_encode(phiP->X, PublicKeyA); -+ fp2_encode(phiQ->X, PublicKeyA + FP2_ENCODED_BYTES); -+ fp2_encode(phiR->X, PublicKeyA + 2*FP2_ENCODED_BYTES); -+ -+ return 0; -+} -+ -+ -+int EphemeralKeyGeneration_B(const unsigned char* PrivateKeyB, unsigned char* PublicKeyB) -+{ -+ point_proj_t R, phiP = POINT_PROJ_INIT, phiQ = POINT_PROJ_INIT, phiR = POINT_PROJ_INIT, pts[MAX_INT_POINTS_BOB]; -+ f2elm_t XPB, XQB, XRB, coeff[3], A24plus = F2ELM_INIT, A24minus = F2ELM_INIT, A = F2ELM_INIT; -+ unsigned int i, row, m, index = 0, pts_index[MAX_INT_POINTS_BOB], npts = 0, ii = 0; -+ -+ // Initialize basis points -+ init_basis((digit_t*)kP503Params.B_gen, XPB, XQB, XRB); -+ init_basis((digit_t*)kP503Params.A_gen, phiP->X, phiQ->X, phiR->X); -+ fpcopy((digit_t*)&kP503Params.Montgomery_one, (phiP->Z)->c0); -+ fpcopy((digit_t*)&kP503Params.Montgomery_one, (phiQ->Z)->c0); -+ fpcopy((digit_t*)&kP503Params.Montgomery_one, (phiR->Z)->c0); -+ -+ // Initialize constants -+ fpcopy((digit_t*)&kP503Params.Montgomery_one, A24plus->c0); -+ fp2add(A24plus, A24plus, A24plus); -+ fp2copy(A24plus, A24minus); -+ fp2neg(A24minus); -+ -+ // Retrieve kernel point -+ LADDER3PT(XPB, XQB, XRB, (digit_t*)PrivateKeyB, BOB, R, A); -+ -+ // Traverse tree -+ index = 0; -+ for (row = 1; row < MAX_Bob; row++) { -+ while (index < MAX_Bob-row) { -+ fp2copy(R->X, pts[npts]->X); -+ fp2copy(R->Z, pts[npts]->Z); -+ pts_index[npts++] = index; -+ m = kP503Params.strat_Bob[ii++]; -+ xTPLe(R, R, A24minus, A24plus, (int)m); -+ index += m; -+ } -+ get_3_isog(R, A24minus, A24plus, coeff); -+ -+ for (i = 0; i < npts; i++) { -+ eval_3_isog(pts[i], coeff); -+ } -+ eval_3_isog(phiP, coeff); -+ eval_3_isog(phiQ, coeff); -+ eval_3_isog(phiR, coeff); -+ -+ fp2copy(pts[npts-1]->X, R->X); -+ fp2copy(pts[npts-1]->Z, R->Z); -+ index = pts_index[npts-1]; -+ npts -= 1; -+ } -+ -+ get_3_isog(R, A24minus, A24plus, coeff); -+ eval_3_isog(phiP, coeff); -+ eval_3_isog(phiQ, coeff); -+ eval_3_isog(phiR, coeff); -+ -+ inv_3_way(phiP->Z, phiQ->Z, phiR->Z); -+ fp2mul_mont(phiP->X, phiP->Z, phiP->X); -+ fp2mul_mont(phiQ->X, phiQ->Z, phiQ->X); -+ fp2mul_mont(phiR->X, phiR->Z, phiR->X); -+ -+ // Format public key -+ fp2_encode(phiP->X, PublicKeyB); -+ fp2_encode(phiQ->X, PublicKeyB + FP2_ENCODED_BYTES); -+ fp2_encode(phiR->X, PublicKeyB + 2*FP2_ENCODED_BYTES); -+ -+ return 0; -+} -+ -+ -+int EphemeralSecretAgreement_A(const unsigned char* PrivateKeyA, const unsigned char* PublicKeyB, unsigned char* SharedSecretA) -+{ -+ point_proj_t R, pts[MAX_INT_POINTS_ALICE]; -+ f2elm_t coeff[3], PKB[3], jinv; -+ f2elm_t A24plus = F2ELM_INIT, C24 = F2ELM_INIT, A = F2ELM_INIT; -+ unsigned int i, row, m, index = 0, pts_index[MAX_INT_POINTS_ALICE], npts = 0, ii = 0; -+ -+ // Initialize images of Bob's basis -+ fp2_decode(PublicKeyB, PKB[0]); -+ fp2_decode(PublicKeyB + FP2_ENCODED_BYTES, PKB[1]); -+ fp2_decode(PublicKeyB + 2*FP2_ENCODED_BYTES, PKB[2]); -+ -+ // Initialize constants -+ get_A(PKB[0], PKB[1], PKB[2], A); // TODO: Can return projective A? -+ fpadd((digit_t*)&kP503Params.Montgomery_one, (digit_t*)&kP503Params.Montgomery_one, C24->c0); -+ fp2add(A, C24, A24plus); -+ fpadd(C24->c0, C24->c0, C24->c0); -+ -+ // Retrieve kernel point -+ LADDER3PT(PKB[0], PKB[1], PKB[2], (digit_t*)PrivateKeyA, ALICE, R, A); -+ -+ // Traverse tree -+ index = 0; -+ for (row = 1; row < MAX_Alice; row++) { -+ while (index < MAX_Alice-row) { -+ fp2copy(R->X, pts[npts]->X); -+ fp2copy(R->Z, pts[npts]->Z); -+ pts_index[npts++] = index; -+ m = kP503Params.strat_Alice[ii++]; -+ xDBLe(R, R, A24plus, C24, (int)(2*m)); -+ index += m; -+ } -+ get_4_isog(R, A24plus, C24, coeff); -+ -+ for (i = 0; i < npts; i++) { -+ eval_4_isog(pts[i], coeff); -+ } -+ -+ fp2copy(pts[npts-1]->X, R->X); -+ fp2copy(pts[npts-1]->Z, R->Z); -+ index = pts_index[npts-1]; -+ npts -= 1; -+ } -+ -+ get_4_isog(R, A24plus, C24, coeff); -+ fp2div2(C24, C24); -+ fp2sub(A24plus, C24, A24plus); -+ fp2div2(C24, C24); -+ j_inv(A24plus, C24, jinv); -+ fp2_encode(jinv, SharedSecretA); // Format shared secret -+ -+ return 0; -+} -+ -+int EphemeralSecretAgreement_B(const unsigned char* PrivateKeyB, const unsigned char* PublicKeyA, unsigned char* SharedSecretB) -+{ -+ point_proj_t R, pts[MAX_INT_POINTS_BOB]; -+ f2elm_t coeff[3], PKB[3], jinv; -+ f2elm_t A24plus = F2ELM_INIT, A24minus = F2ELM_INIT, A = F2ELM_INIT; -+ unsigned int i, row, m, index = 0, pts_index[MAX_INT_POINTS_BOB], npts = 0, ii = 0; -+ -+ // Initialize images of Alice's basis -+ fp2_decode(PublicKeyA, PKB[0]); -+ fp2_decode(PublicKeyA + FP2_ENCODED_BYTES, PKB[1]); -+ fp2_decode(PublicKeyA + 2*FP2_ENCODED_BYTES, PKB[2]); -+ -+ // Initialize constants -+ get_A(PKB[0], PKB[1], PKB[2], A); // TODO: Can return projective A? -+ fpadd((digit_t*)&kP503Params.Montgomery_one, (digit_t*)&kP503Params.Montgomery_one, A24minus->c0); -+ fp2add(A, A24minus, A24plus); -+ fp2sub(A, A24minus, A24minus); -+ -+ // Retrieve kernel point -+ LADDER3PT(PKB[0], PKB[1], PKB[2], (digit_t*)PrivateKeyB, BOB, R, A); -+ -+ // Traverse tree -+ index = 0; -+ for (row = 1; row < MAX_Bob; row++) { -+ while (index < MAX_Bob-row) { -+ fp2copy(R->X, pts[npts]->X); -+ fp2copy(R->Z, pts[npts]->Z); -+ pts_index[npts++] = index; -+ m = kP503Params.strat_Bob[ii++]; -+ xTPLe(R, R, A24minus, A24plus, (int)m); -+ index += m; -+ } -+ get_3_isog(R, A24minus, A24plus, coeff); -+ -+ for (i = 0; i < npts; i++) { -+ eval_3_isog(pts[i], coeff); -+ } -+ -+ fp2copy(pts[npts-1]->X, R->X); -+ fp2copy(pts[npts-1]->Z, R->Z); -+ index = pts_index[npts-1]; -+ npts -= 1; -+ } -+ -+ get_3_isog(R, A24minus, A24plus, coeff); -+ fp2add(A24plus, A24minus, A); -+ fp2add(A, A, A); -+ fp2sub(A24plus, A24minus, A24plus); -+ j_inv(A, A24plus, jinv); -+ fp2_encode(jinv, SharedSecretB); // Format shared secret -+ -+ return 0; -+} -+ -+int EphemeralKeyPair_SIDHp503(unsigned char* PrivateKey, unsigned char* PublicKey, int IsInitiator) { -+ int ret = -1; -+ -+ BN_CTX *ctx = BN_CTX_new(); -+ if (!ctx) { -+ goto end; -+ } -+ -+ // Calculate private key for Alice. Needs to be in range [0, 2^0xFA - 1] and < 250 bits -+ BIGNUM *bn_sidh_prv = BN_CTX_get(ctx); -+ if (!bn_sidh_prv) { -+ goto end; -+ } -+ -+ if (!BN_rand(bn_sidh_prv, PrvKeyBitSz(IsInitiator), BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) { -+ goto end; -+ } -+ -+ // Convert to little endian -+ if (!BN_bn2le_padded(PrivateKey, NBITS_TO_NBYTES(PrvKeyBitSz(IsInitiator)), bn_sidh_prv)) { -+ goto end; -+ } -+ -+ // Never fails -+ IsInitiator -+ ?(void)EphemeralKeyGeneration_A_SIDHp503(PrivateKey, PublicKey) -+ :(void)EphemeralKeyGeneration_B_SIDHp503(PrivateKey, PublicKey); -+ -+ // All good -+ ret = 0; -+ -+end: -+ BN_CTX_free(ctx); -+ return ret; -+} -diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt -index 7f340171d..6a796cc48 100644 ---- a/tool/CMakeLists.txt -+++ b/tool/CMakeLists.txt -@@ -1,4 +1,4 @@ --include_directories(../include) -+include_directories(../include ../third_party/sidh/include) - - add_executable( - bssl -diff --git a/tool/speed.cc b/tool/speed.cc -index 2175baa24..4d86441ea 100644 ---- a/tool/speed.cc -+++ b/tool/speed.cc -@@ -50,6 +50,10 @@ OPENSSL_MSVC_PRAGMA(warning(pop)) - #include "internal.h" - - -+#include "sidh/def_p503.h" -+#include "sidh/P503_api.h" -+ -+ - // TimeResults represents the results of benchmarking a function. - struct TimeResults { - // num_calls is the number of function calls done in the time period. -@@ -282,6 +286,78 @@ static bool SpeedRSAKeyGen(const std::string &selected) { - return true; - } - -+static bool SpeedSIDHP503KeyGen(bool is_initiator) { -+ uint8_t public_SIDH[SIDHp503_PUB_BYTESZ] = {0}; -+ uint8_t private_SIDH[SIDHp503_PRV_KEY_BYTESZ_MAX] = {0}; -+ // Key generation function to be benchmarked -+ std::function keygen = -+ is_initiator? -+ EphemeralKeyGeneration_A_SIDHp503: -+ EphemeralKeyGeneration_B_SIDHp503; -+ -+ // Generate private key to be used for public key generation -+ if (EphemeralKeyPair_SIDHp503(private_SIDH, public_SIDH, is_initiator)) { -+ return false; -+ } -+ -+ TimeResults results; -+ TimeFunction(&results, -+ [keygen, &private_SIDH, &public_SIDH]() -> bool { -+ // Never fails -+ (void)keygen(private_SIDH, public_SIDH); -+ return true; -+ }); -+ -+ results.Print(std::string("SIDH/P503 KeyGen ") + std::string(is_initiator?"A":"B")); -+ return true; -+} -+ -+static bool SpeedSIDHP503Kex(bool is_initiator) { -+ uint8_t public_SIDH[SIDHp503_PUB_BYTESZ] = {0}; -+ uint8_t private_SIDH[SIDHp503_PRV_KEY_BYTESZ_MAX] = {0}; -+ uint8_t tmp[SIDHp503_PRV_KEY_BYTESZ_MAX] = {0}; -+ uint8_t ss[SIDHp503_SS_BYTESZ] = {0}; -+ -+ // Key agreement function to be benchmarked -+ std::function kex = -+ is_initiator? -+ EphemeralSecretAgreement_A_SIDHp503: -+ EphemeralSecretAgreement_B_SIDHp503; -+ -+ // Generate private key for one side -+ if (EphemeralKeyPair_SIDHp503(private_SIDH, public_SIDH, is_initiator)) { -+ return false; -+ } -+ -+ // Generate public key for other side -+ memset(public_SIDH, 0, sizeof(public_SIDH)); -+ if (EphemeralKeyPair_SIDHp503(tmp, public_SIDH, !is_initiator)) { -+ return false; -+ } -+ -+ TimeResults results; -+ TimeFunction(&results, -+ [kex, &private_SIDH, &public_SIDH, &ss]() -> bool { -+ // Never fails -+ (void)kex(private_SIDH, public_SIDH, ss); -+ return true; -+ }); -+ -+ results.Print(std::string("SIDH/P503 KEX ") + std::string(is_initiator?"A":"B")); -+ return true; -+} -+ -+static bool SpeedSIDHP503(const std::string &selected) { -+ if (!selected.empty() && selected.find("SIDH") == std::string::npos) { -+ return true; -+ } -+ return -+ SpeedSIDHP503KeyGen(true) && -+ SpeedSIDHP503KeyGen(false) && -+ SpeedSIDHP503Kex(true) && -+ SpeedSIDHP503Kex(false); -+} -+ - static uint8_t *align(uint8_t *in, unsigned alignment) { - return reinterpret_cast( - (reinterpret_cast(in) + alignment) & -@@ -815,6 +891,7 @@ bool Speed(const std::vector &args) { - !SpeedECDH(selected) || - !SpeedECDSA(selected) || - !Speed25519(selected) || -+ !SpeedSIDHP503(selected) || - !SpeedSPAKE2(selected) || - !SpeedScrypt(selected) || - !SpeedRSAKeyGen(selected)) { diff --git a/_dev/caddy/Caddyfile b/_dev/caddy/Caddyfile deleted file mode 100644 index a6e635c..0000000 --- a/_dev/caddy/Caddyfile +++ /dev/null @@ -1,13 +0,0 @@ -tris.filippo.io { - tls bip@filippo.io - log stdout - proxy / https://blog.filippo.io -} - -echo.filippo.io { - tls bip@filippo.io - log stdout - proxy / http://{$ECHO_PORT_80_TCP_ADDR}:{$ECHO_PORT_80_TCP_PORT} { - transparent - } -} diff --git a/_dev/caddy/Dockerfile b/_dev/caddy/Dockerfile deleted file mode 100644 index b1ad2f9..0000000 --- a/_dev/caddy/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM scratch - -# docker create -v /root/.caddy --name caddy-data caddy /bin/true -# docker run --restart=always -d --volumes-from caddy-data --link echo -p 80:80 -p 443:443 caddy - -# GOOS=linux ../go.sh build -v -i github.com/mholt/caddy/caddy -ADD caddy caddy -ADD Caddyfile Caddyfile -ADD https://mkcert.org/generate/ /etc/ssl/certs/ca-certificates.crt - -EXPOSE 80 -EXPOSE 443 - -ENV TLSDEBUG short -ENV HOME /root/ - -CMD [ "/caddy" ] diff --git a/_dev/caddy/Dockerfile.echo b/_dev/caddy/Dockerfile.echo deleted file mode 100644 index f3781a1..0000000 --- a/_dev/caddy/Dockerfile.echo +++ /dev/null @@ -1,7 +0,0 @@ -FROM scratch - -# docker run --restart=always -d --name echo -P echo - -ADD echo echo -EXPOSE 80 -CMD [ "/echo", "0.0.0.0:80" ] diff --git a/_dev/caddy/caddy.patch b/_dev/caddy/caddy.patch deleted file mode 100644 index f84f509..0000000 --- a/_dev/caddy/caddy.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff --git a/caddytls/config.go b/caddytls/config.go -index 6632aed..767886c 100644 ---- a/caddytls/config.go -+++ b/caddytls/config.go -@@ -372,7 +372,7 @@ func SetDefaultTLSParams(config *Config) { - config.ProtocolMinVersion = tls.VersionTLS11 - } - if config.ProtocolMaxVersion == 0 { -- config.ProtocolMaxVersion = tls.VersionTLS12 -+ config.ProtocolMaxVersion = tls.VersionTLS13 - } - - // Prefer server cipher suites -@@ -394,6 +394,7 @@ var supportedProtocols = map[string]uint16{ - "tls1.0": tls.VersionTLS10, - "tls1.1": tls.VersionTLS11, - "tls1.2": tls.VersionTLS12, -+ "tls1.3": tls.VersionTLS13, - } - - // Map of supported ciphers, used only for parsing config. diff --git a/_dev/caddy/echo.go b/_dev/caddy/echo.go deleted file mode 100644 index ab5d612..0000000 --- a/_dev/caddy/echo.go +++ /dev/null @@ -1,25 +0,0 @@ -package main - -import ( - "fmt" - "html" - "log" - "net/http" - "os" -) - -var htmlBody = []byte(` - -

Hello! -

-`)
-
-func main() {
-	http.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
-		rw.Write(htmlBody)
-		for name, value := range r.Header {
-			fmt.Fprintf(rw, "%s: %s\n", name, html.EscapeString(value[0]))
-		}
-	})
-	log.Println(http.ListenAndServe(os.Args[1], nil))
-}
diff --git a/_dev/go.sh b/_dev/go.sh
deleted file mode 100755
index 91403a3..0000000
--- a/_dev/go.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env bash
-# 
-# THIS FILE IS ONLY USED BY _dev/bogo. It will be removed in future
-set -e
-
-BASEDIR=$(cd "$(dirname "$0")" && pwd)
-GOENV="$(go env GOHOSTOS)_$(go env GOHOSTARCH)"
-
-BUILD_DIR=${BASEDIR}/GOROOT make -f $BASEDIR/Makefile >&2
-
-export GOROOT="$BASEDIR/GOROOT/$GOENV"
-exec go "$@"
diff --git a/_dev/interop_test_runner b/_dev/interop_test_runner
deleted file mode 100755
index 5fe9577..0000000
--- a/_dev/interop_test_runner
+++ /dev/null
@@ -1,308 +0,0 @@
-#!/usr/bin/env python2
-
-import docker
-import unittest
-import re
-import time
-
-# Regex patterns used for testing
-
-# Checks if TLS 1.3 was negotiated
-RE_PATTERN_HELLO_TLS_13_NORESUME = "^.*Hello TLS 1.3 \(draft .*\) _o/$|^.*Hello TLS 1.3 _o/$"
-# Checks if TLS 1.3 was resumed
-RE_PATTERN_HELLO_TLS_13_RESUME   = "Hello TLS 1.3 \[resumed\] _o/"
-# Checks if 0-RTT was used and NOT confirmed
-RE_PATTERN_HELLO_0RTT            = "^.*Hello TLS 1.3 .*\[resumed\] \[0-RTT\] _o/$"
-# Checks if 0-RTT was used and confirmed
-RE_PATTERN_HELLO_0RTT_CONFIRMED  = "^.*Hello TLS 1.3 .*\[resumed\] \[0-RTT confirmed\] _o/$"
-# ALPN
-RE_PATTERN_ALPN = "ALPN protocol: npn_proto$"
-# Successful TLS establishement from TRIS
-RE_TRIS_ALL_PASSED = ".*All handshakes passed.*"
-# TLS handshake from BoringSSL with SIDH/P503-X25519
-RE_BORINGSSL_P503 = "ECDHE curve: X25519-SIDHp503"
-
-class Docker(object):
-    ''' Utility class used for starting/stoping servers and clients during tests'''
-    def __init__(self):
-        self.d = docker.from_env()
-
-    def get_ip(self, server):
-        tris_localserver_container = self.d.containers.get(server)
-        return tris_localserver_container.attrs['NetworkSettings']['IPAddress']
-
-    def run_client(self, image_name, cmd):
-        ''' Runs client and returns tuple (status_code, logs) '''
-        c = self.d.containers.create(image=image_name, command=cmd)
-        c.start()
-        res = c.wait()
-        ret = c.logs()
-        c.remove()
-        return (res['StatusCode'], ret)
-
-    def run_server(self, image_name, cmd=None, ports=None, entrypoint=None):
-        ''' Starts server and returns docker container '''
-        c = self.d.containers.create(image=image_name, detach=True, command=cmd, ports=ports, entrypoint=entrypoint)
-        c.start()
-        # TODO: maybe can be done better?
-        time.sleep(3)
-        return c
-
-class RegexSelfTest(unittest.TestCase):
-    ''' Ensures that those regexe's actually work '''
-
-    LINE_HELLO_TLS      ="\nsomestuff\nHello TLS 1.3 _o/\nsomestuff"
-    LINE_HELLO_DRAFT_TLS="\nsomestuff\nHello TLS 1.3 (draft 23) _o/\nsomestuff"
-
-    LINE_HELLO_RESUMED  ="\nsomestuff\nHello TLS 1.3 [resumed] _o/\nsomestuff"
-    LINE_HELLO_MIXED    ="\nsomestuff\nHello TLS 1.3 (draft 23) _o/\nHello TLS 1.3 (draft 23) [resumed] _o/\nsomestuff"
-    LINE_HELLO_TLS_12   ="\nsomestuff\nHello TLS 1.2 (draft 23) [resumed] _o/\nsomestuff"
-    LINE_HELLO_TLS_13_0RTT="\nsomestuff\nHello TLS 1.3 (draft 23) [resumed] [0-RTT] _o/\nsomestuff"
-    LINE_HELLO_TLS_13_0RTT_CONFIRMED="\nsomestuff\nHello TLS 1.3 (draft 23) [resumed] [0-RTT confirmed] _o/\nsomestuff"
-    def test_regexes(self):
-        self.assertIsNotNone(
-            re.search(RE_PATTERN_HELLO_TLS_13_NORESUME, RegexSelfTest.LINE_HELLO_TLS, re.MULTILINE))
-        self.assertIsNotNone(
-            re.search(RE_PATTERN_HELLO_TLS_13_NORESUME, RegexSelfTest.LINE_HELLO_DRAFT_TLS, re.MULTILINE))
-        self.assertIsNotNone(
-            re.search(RE_PATTERN_HELLO_TLS_13_RESUME, RegexSelfTest.LINE_HELLO_RESUMED, re.MULTILINE))
-        self.assertIsNotNone(
-            re.search(RE_PATTERN_HELLO_0RTT, RegexSelfTest.LINE_HELLO_TLS_13_0RTT, re.MULTILINE))
-        self.assertIsNotNone(
-            re.search(RE_PATTERN_HELLO_0RTT_CONFIRMED, RegexSelfTest.LINE_HELLO_TLS_13_0RTT_CONFIRMED, re.MULTILINE))
-
-        # negative cases
-
-        # expects 1.3, but 1.2 received
-        self.assertIsNone(
-            re.search(RE_PATTERN_HELLO_TLS_13_NORESUME, RegexSelfTest.LINE_HELLO_TLS_12, re.MULTILINE))
-        # expects 0-RTT
-        self.assertIsNone(
-            re.search(RE_PATTERN_HELLO_TLS_13_RESUME, RegexSelfTest.LINE_HELLO_TLS_13_0RTT, re.MULTILINE))
-        # expectes 0-RTT confirmed
-        self.assertIsNone(
-            re.search(RE_PATTERN_HELLO_0RTT, RegexSelfTest.LINE_HELLO_TLS_13_0RTT_CONFIRMED, re.MULTILINE))
-        # expects resume without 0-RTT
-        self.assertIsNone(
-            re.search(RE_PATTERN_HELLO_TLS_13_RESUME, RegexSelfTest.LINE_HELLO_TLS_13_0RTT, re.MULTILINE))
-
-
-class InteropServer(object):
-    ''' Instantiates TRIS as a server '''
-
-    TRIS_SERVER_NAME = "tris-localserver"
-
-    @classmethod
-    def setUpClass(self):
-        self.d = Docker()
-        self.server = self.d.run_server(self.TRIS_SERVER_NAME)
-
-    @classmethod
-    def tearDownClass(self):
-        self.server.kill()
-        self.server.remove()
-
-    @property
-    def server_ip(self):
-        return self.d.get_ip(self.server.name)
-
-# Mixins for testing server functionality
-
-class ServerNominalMixin(object):
-    ''' Nominal tests for TLS 1.3 - client tries to perform handshake with server '''
-    def test_rsa(self):
-        res = self.d.run_client(self.CLIENT_NAME, self.server_ip+":"+'1443')
-        self.assertTrue(res[0] == 0)
-        # Check there was TLS hello without resume
-        self.assertIsNotNone(
-            re.search(RE_PATTERN_HELLO_TLS_13_NORESUME, res[1], re.MULTILINE))
-        # Check there was TLS hello with resume
-        self.assertIsNotNone(
-            re.search(RE_PATTERN_HELLO_TLS_13_RESUME, res[1], re.MULTILINE))
-
-    def test_ecdsa(self):
-        res = self.d.run_client(self.CLIENT_NAME, self.server_ip+":"+'2443')
-        self.assertTrue(res[0] == 0)
-        # Check there was TLS hello without resume
-        self.assertIsNotNone(
-            re.search(RE_PATTERN_HELLO_TLS_13_NORESUME, res[1], re.MULTILINE))
-        # Check there was TLS hello with resume
-        self.assertIsNotNone(
-            re.search(RE_PATTERN_HELLO_TLS_13_RESUME, res[1], re.MULTILINE))
-
-class ServerClientAuthMixin(object):
-    ''' Client authentication testing '''
-    def test_client_auth(self):
-        args = ''.join([self.server_ip+':6443',' -key client_rsa.key -cert client_rsa.crt -debug'])
-        res = self.d.run_client(self.CLIENT_NAME, args)
-        self.assertEqual(res[0], 0)
-        # Check there was TLS hello without resume
-        self.assertIsNotNone(
-            re.search(RE_PATTERN_HELLO_TLS_13_NORESUME, res[1], re.MULTILINE))
-        # Check there was TLS hello with resume
-        self.assertIsNotNone(
-            re.search(RE_PATTERN_HELLO_TLS_13_RESUME, res[1], re.MULTILINE))
-
-class ClientNominalMixin(object):
-
-    def test_rsa(self):
-        res = self.d.run_client(self.CLIENT_NAME, '-ecdsa=false '+self.server_ip+":1443")
-        self.assertEqual(res[0], 0)
-
-    def test_ecdsa(self):
-        res = self.d.run_client(self.CLIENT_NAME, '-rsa=false '+self.server_ip+":2443")
-        self.assertEqual(res[0], 0)
-
-
-class ClientClientAuthMixin(object):
-    ''' Client authentication testing - tris on client side '''
-
-    def test_client_auth(self):
-        res = self.d.run_client('tris-testclient', '-rsa=false -cliauth '+self.server_ip+":6443")
-        self.assertTrue(res[0] == 0)
-
-class ServerZeroRttMixin(object):
-    ''' Zero RTT testing '''
-
-    def test_zero_rtt(self):
-        # rejecting 0-RTT
-        res = self.d.run_client(self.CLIENT_NAME, self.server_ip+":3443")
-        self.assertEqual(res[0], 0)
-        self.assertIsNotNone(
-            re.search(RE_PATTERN_HELLO_TLS_13_RESUME, res[1], re.MULTILINE))
-        self.assertIsNone(
-            re.search(RE_PATTERN_HELLO_0RTT, res[1], re.MULTILINE))
-
-        # accepting 0-RTT
-        res = self.d.run_client(self.CLIENT_NAME, self.server_ip+":4443")
-        self.assertEqual(res[0], 0)
-        self.assertIsNotNone(
-            re.search(RE_PATTERN_HELLO_0RTT, res[1], re.MULTILINE))
-
-        # confirming 0-RTT
-        res = self.d.run_client(self.CLIENT_NAME, self.server_ip+":5443")
-        self.assertEqual(res[0], 0)
-        self.assertIsNotNone(
-            re.search(RE_PATTERN_HELLO_0RTT_CONFIRMED, res[1], re.MULTILINE))
-
-class InteropClient(object):
-    ''' Instantiates TRIS as a client '''
-
-    CLIENT_NAME = "tris-testclient"
-
-    @classmethod
-    def setUpClass(self):
-        self.d = Docker()
-        self.server = self.d.run_server(
-                            self.SERVER_NAME,
-                            ports={ '1443/tcp': 1443, '2443/tcp': 2443, '6443/tcp': 6443, '7443/tcp': 7443},
-                            entrypoint="/server.sh")
-
-    @classmethod
-    def tearDownClass(self):
-        self.server.kill()
-        self.server.remove()
-
-    @property
-    def server_ip(self):
-        return self.d.get_ip(self.server.name)
-
-# Actual test definition
-
-# TRIS as a server, BoringSSL as a client
-class InteropServer_BoringSSL(InteropServer, ServerNominalMixin, ServerClientAuthMixin, unittest.TestCase):
-
-    CLIENT_NAME = "tls-tris:boring"
-
-    def test_ALPN(self):
-        '''
-        Checks wether ALPN is sent back by tris server in EncryptedExtensions in case of TLS 1.3. The
-        ALPN protocol is set to 'npn_proto', which is hardcoded in TRIS test server.
-        '''
-        res = self.d.run_client(self.CLIENT_NAME, self.server_ip+":1443 "+'-alpn-protos npn_proto')
-        self.assertEqual(res[0], 0)
-        self.assertIsNotNone(re.search(RE_PATTERN_ALPN, res[1], re.MULTILINE))
-
-    def test_SIDH(self):
-        '''
-        Connects to TRIS server listening on 7443 and tries to perform key agreement with SIDH/P503-X25519
-        '''
-        res = self.d.run_client(self.CLIENT_NAME, self.server_ip+":7443 "+'-curves X25519-SIDHp503')
-        self.assertEqual(res[0], 0)
-        self.assertIsNotNone(re.search(RE_BORINGSSL_P503, res[1], re.MULTILINE))
-        self.assertIsNotNone(re.search(RE_PATTERN_HELLO_TLS_13_NORESUME, res[1], re.MULTILINE))
-
-# PicoTLS doesn't seem to implement draft-23 correctly. It will
-# be enabled when draft-28 is implemented.
-# class InteropServer_PicoTLS(
-#         InteropServer,
-#         ServerNominalMixin,
-#         ServerZeroRttMixin,
-#         unittest.TestCase
-#     ): CLIENT_NAME = "tls-tris:picotls"
-
-class InteropServer_NSS(
-        InteropServer,
-        ServerNominalMixin,
-        ServerZeroRttMixin,
-        unittest.TestCase
-    ): CLIENT_NAME = "tls-tris:tstclnt"
-
-# TRIS as a client, BoringSSL as a server
-class InteropClient_BoringSSL(InteropClient, ClientNominalMixin, ClientClientAuthMixin, unittest.TestCase):
-
-    SERVER_NAME = "boring-localserver"
-
-    def test_SIDH(self):
-        '''
-        Connects to BoringSSL server listening on 7443 and tries to perform key agreement with SIDH/P503-X25519
-        '''
-        res = self.d.run_client(self.CLIENT_NAME, '-rsa=false -ecdsa=true -groups X25519-SIDHp503 ' + self.server_ip+":7443")
-        self.assertEqual(res[0], 0)
-        self.assertIsNotNone(re.search(RE_TRIS_ALL_PASSED, res[1], re.MULTILINE))
-
-    def test_SIDH_TLSv12(self):
-        '''
-        Connects to TRIS server listening on 7443 and tries to perform key agreement with SIDH/P503-X25519
-        This connection will be over TLSv12 and hence it should fall back to X25519
-        '''
-        res = self.d.run_client(self.CLIENT_NAME, '-tls_version=1.2 -rsa=false -ecdsa=true -groups X25519-SIDHp503:P-256 -ciphers TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 ' + self.server_ip+":7443")
-        self.assertEqual(res[0], 0)
-        # Go doesn't provide API to get NamedGroup ID, but boringssl on port 7443 accepts only TLS1.2
-        # so if handshake was successful, then that's all what we need
-        self.assertIsNotNone(re.search(RE_TRIS_ALL_PASSED, res[1], re.MULTILINE))
-
-class InteropClient_NSS(
-        InteropClient,
-        ClientNominalMixin,
-        unittest.TestCase
-    ): SERVER_NAME = "tstclnt-localserver"
-
-# TRIS as a client
-class InteropServer_TRIS(ClientNominalMixin, InteropServer, unittest.TestCase):
-
-    CLIENT_NAME = 'tris-testclient'
-
-    def test_client_auth(self):
-        # I need to block TLS v1.2 as test server needs some rework
-        res = self.d.run_client(self.CLIENT_NAME, '-rsa=false -ecdsa=false -cliauth '+self.server_ip+":6443")
-        self.assertEqual(res[0], 0)
-
-    def test_SIDH(self):
-        res = self.d.run_client(self.CLIENT_NAME, '-rsa=false -ecdsa=true -groups X25519-SIDHp503 '+self.server_ip+":7443")
-        self.assertEqual(res[0], 0)
-
-    def test_SIKE(self):
-        res = self.d.run_client(self.CLIENT_NAME, '-rsa=false -ecdsa=true -groups X25519-SIKEp503 '+self.server_ip+":7443")
-        self.assertEqual(res[0], 0)
-
-    def test_server_doesnt_support_SIDH(self):
-        '''
-        Client advertises HybridSIDH and ECDH. Server supports ECDH only. Checks weather
-        TLS session can still be established.
-        '''
-        res = self.d.run_client(self.CLIENT_NAME, '-rsa=false -ecdsa=true '+self.server_ip+":7443")
-        self.assertEqual(res[0], 0)
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/_dev/mint/Dockerfile b/_dev/mint/Dockerfile
deleted file mode 100644
index 03004dd..0000000
--- a/_dev/mint/Dockerfile
+++ /dev/null
@@ -1,21 +0,0 @@
-FROM golang:1.7-alpine
-
-RUN apk add --update \
-    git \
-  && rm -rf /var/cache/apk/*
-
-RUN go get github.com/bifurcation/mint
-
-# Draft 18
-ARG REVISION=52f9f98
-
-RUN cd /go/src/github.com/bifurcation/mint && git fetch https://github.com/FiloSottile/mint
-RUN cd /go/src/github.com/bifurcation/mint && git checkout $REVISION
-
-ADD mint-client.go /mint-client.go
-RUN GOBIN=/ go install /mint-client.go
-
-ENV MINT_LOG=*
-
-ADD run.sh /run.sh
-ENTRYPOINT ["/run.sh"]
diff --git a/_dev/mint/mint-client.go b/_dev/mint/mint-client.go
deleted file mode 100644
index 3a59bde..0000000
--- a/_dev/mint/mint-client.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package main
-
-import (
-	"log"
-	"net"
-	"net/http"
-	"os"
-
-	"github.com/bifurcation/mint"
-)
-
-func main() {
-	c := &mint.Config{
-		PSKs: &mint.PSKMapCache{},
-	}
-
-	tr := &http.Transport{
-		DialTLS: func(network, addr string) (net.Conn, error) {
-			return mint.Dial(network, addr, c)
-		},
-		DisableKeepAlives: true,
-	}
-	client := &http.Client{Transport: tr}
-
-	resp, err := client.Get("https://" + os.Args[1])
-	if err != nil {
-		log.Fatal(err)
-	}
-	if err := resp.Write(os.Stdout); err != nil {
-		log.Fatal(err)
-	}
-
-	// Resumption
-	resp, err = client.Get("https://" + os.Args[1])
-	if err != nil {
-		log.Fatal(err)
-	}
-	if err := resp.Write(os.Stdout); err != nil {
-		log.Fatal(err)
-	}
-}
diff --git a/_dev/mint/run.sh b/_dev/mint/run.sh
deleted file mode 100755
index 013915a..0000000
--- a/_dev/mint/run.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#! /bin/sh
-
-exec /mint-client "$@"
diff --git a/_dev/patches/88253a956a753213617d95af3f42a23a78798473.patch b/_dev/patches/88253a956a753213617d95af3f42a23a78798473.patch
deleted file mode 100644
index 582be1e..0000000
--- a/_dev/patches/88253a956a753213617d95af3f42a23a78798473.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 88253a956a753213617d95af3f42a23a78798473 Mon Sep 17 00:00:00 2001
-From: Filippo Valsorda 
-Date: Mon, 28 Nov 2016 05:24:21 +0000
-Subject: [PATCH] net/http: attach TLSConnContextKey to the request Context
-
-Change-Id: Ic59c84f992c829dc7da741b128dd6899366fa1d2
----
- src/net/http/request.go |  4 +++-
- src/net/http/server.go  | 12 ++++++++++++
- 2 files changed, 15 insertions(+), 1 deletion(-)
-
-diff --git a/src/net/http/request.go b/src/net/http/request.go
-index 13f367c1a8..b2827ff123 100644
---- a/src/net/http/request.go
-+++ b/src/net/http/request.go
-@@ -275,7 +275,9 @@ type Request struct {
- 	// was received. This field is not filled in by ReadRequest.
- 	// The HTTP server in this package sets the field for
- 	// TLS-enabled connections before invoking a handler;
--	// otherwise it leaves the field nil.
-+	// otherwise it leaves the field nil. The value is fixed
-+	// at the state of the connection immediately after Handshake,
-+	// for an immediate value use TLSConnContextKey.
- 	// This field is ignored by the HTTP client.
- 	TLS *tls.ConnectionState
- 
-diff --git a/src/net/http/server.go b/src/net/http/server.go
-index 2fa8ab23d8..b0542cdbc3 100644
---- a/src/net/http/server.go
-+++ b/src/net/http/server.go
-@@ -223,6 +223,12 @@ var (
- 	// the local address the connection arrived on.
- 	// The associated value will be of type net.Addr.
- 	LocalAddrContextKey = &contextKey{"local-addr"}
-+
-+	// TLSConnContextKey is a context key. It can be used in
-+	// HTTP handlers with context.WithValue to access the
-+	// underlying *tls.Conn being served. If the connection
-+	// is not TLS, the key is not set.
-+	TLSConnContextKey = &contextKey{"tls-conn"}
- )
- 
- // A conn represents the server side of an HTTP connection.
-@@ -969,6 +975,9 @@ func (c *conn) readRequest(ctx context.Context) (w *response, err error) {
- 	delete(req.Header, "Host")
- 
- 	ctx, cancelCtx := context.WithCancel(ctx)
-+	if tlsConn, ok := c.rwc.(*tls.Conn); ok {
-+		ctx = context.WithValue(ctx, TLSConnContextKey, tlsConn)
-+	}
- 	req.ctx = ctx
- 	req.RemoteAddr = c.remoteAddr
- 	req.TLS = c.tlsState
-@@ -3161,6 +3170,9 @@ func (h initNPNRequest) ServeHTTP(rw ResponseWriter, req *Request) {
- 	if req.RemoteAddr == "" {
- 		req.RemoteAddr = h.c.RemoteAddr().String()
- 	}
-+	if req.ctx != nil && req.ctx.Value(TLSConnContextKey) == nil {
-+		req.ctx = context.WithValue(req.ctx, TLSConnContextKey, h.c)
-+	}
- 	h.h.ServeHTTP(rw, req)
- }
- 
diff --git a/_dev/picotls/Dockerfile b/_dev/picotls/Dockerfile
deleted file mode 100644
index 224567b..0000000
--- a/_dev/picotls/Dockerfile
+++ /dev/null
@@ -1,26 +0,0 @@
-FROM alpine
-
-RUN apk add --update \
-    git \
-    cmake \
-    build-base \
-    openssl-dev \
-    bash \
-  && rm -rf /var/cache/apk/*
-
-RUN git clone https://github.com/h2o/picotls
-
-# Draft -18
-#ARG REVISION=a6c1c65
-
-# Draft -22
-ARG REVISION=843ccdc
-
-RUN cd picotls && git fetch && git checkout $REVISION
-
-RUN cd picotls && git submodule update --init
-RUN cd picotls && cmake . && make
-
-ADD httpreq.txt /httpreq.txt
-ADD run.sh /run.sh
-ENTRYPOINT ["/run.sh"]
diff --git a/_dev/picotls/httpreq.txt b/_dev/picotls/httpreq.txt
deleted file mode 100644
index e4e6ac1..0000000
--- a/_dev/picotls/httpreq.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-GET / HTTP/1.1
-Host: example.com
-Connection: close
-
-
diff --git a/_dev/picotls/run.sh b/_dev/picotls/run.sh
deleted file mode 100755
index e7e278c..0000000
--- a/_dev/picotls/run.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#! /bin/bash
-set -e
-
-IFS=':' read -ra ADDR <<< "$1"
-shift
-HOST="${ADDR[0]}"
-PORT="${ADDR[1]}"
-
-/picotls/cli -s /session -e "$@" $HOST $PORT < /httpreq.txt
-/picotls/cli -s /session -e "$@" $HOST $PORT < /httpreq.txt
diff --git a/_dev/testdata/Dockerfile b/_dev/testdata/Dockerfile
deleted file mode 100644
index ca3ad08..0000000
--- a/_dev/testdata/Dockerfile
+++ /dev/null
@@ -1,26 +0,0 @@
-# docker build -t tls-tris:testdata _dev/testdata
-# GOOS=linux ./_dev/go.sh test -c crypto/tls
-# docker run -it --rm -v "$(pwd):$(pwd)" -w "$(pwd)" tls-tris:testdata 
-# ./tls.test -update -test.v -test.run SCTs
-## === RUN   TestHandshakClientSCTs
-## Wrote testdata/Client-TLSv12-SCT
-## --- PASS: TestHandshakClientSCTs (0.62s)
-## PASS
-
-FROM alpine
-
-RUN apk add --update \
-		wget \
-		build-base \
-		perl \
-		ca-certificates \
-		linux-headers \
-	&& rm -rf /var/cache/apk/*
-
-RUN wget https://www.openssl.org/source/openssl-1.1.0c.tar.gz
-RUN tar xvf openssl-1.1.0c.tar.gz
-RUN cd openssl-1.1.0c && perl ./Configure enable-weak-ssl-ciphers enable-ssl3 enable-ssl3-method -static linux-x86_64
-RUN cd openssl-1.1.0c && make
-RUN cd openssl-1.1.0c && make install
-
-ENTRYPOINT ["/bin/sh"]
diff --git a/_dev/tls_examples/Makefile b/_dev/tls_examples/Makefile
deleted file mode 100644
index 6a49d52..0000000
--- a/_dev/tls_examples/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# Used to build examples. Must be compiled from current directory and after "make build-all"
-
-build:
-	GOROOT=../GOROOT/linux_amd64 go build ems_client.go
-
-run:
-	./ems_client google.com:443
diff --git a/_dev/tls_examples/ems_client.go b/_dev/tls_examples/ems_client.go
deleted file mode 100644
index f99a50d..0000000
--- a/_dev/tls_examples/ems_client.go
+++ /dev/null
@@ -1,75 +0,0 @@
-package main
-
-import (
-	"bufio"
-	"crypto/tls"
-	"flag"
-	"fmt"
-	"io"
-	"net/http"
-	"net/url"
-	"os"
-)
-
-var tlsVersionToName = map[string]uint16{
-	"tls10": tls.VersionTLS10,
-	"tls11": tls.VersionTLS11,
-	"tls12": tls.VersionTLS12,
-	"tls13": tls.VersionTLS13,
-}
-
-// Usage client args host:port
-func main() {
-	var version string
-	var addr string
-	var enableEMS bool
-	var resume bool
-	var config tls.Config
-	var cache tls.ClientSessionCache
-	cache = tls.NewLRUClientSessionCache(0)
-	flag.StringVar(&version, "version", "tls12", "Version of TLS to use")
-	flag.BoolVar(&enableEMS, "m", false, "Enable EMS")
-	flag.BoolVar(&resume, "r", false, "Attempt Resumption")
-	flag.Parse()
-	config.MinVersion = tlsVersionToName[version]
-	config.MaxVersion = tlsVersionToName[version]
-	config.InsecureSkipVerify = true
-	config.UseExtendedMasterSecret = !enableEMS
-	config.ClientSessionCache = cache
-	var iters int
-	if resume {
-		iters = 2
-	} else {
-		iters = 1
-	}
-	addr = flag.Arg(0)
-	for ; iters > 0; iters-- {
-		conn, err := tls.Dial("tcp", addr, &config)
-		if err != nil {
-			fmt.Println("Error %s", err)
-			os.Exit(1)
-		}
-		var req http.Request
-		var response *http.Response
-		req.Method = "GET"
-		req.URL, err = url.Parse("https://" + addr + "/")
-		if err != nil {
-			fmt.Println("Failed to parse url")
-			os.Exit(1)
-		}
-		req.Write(conn)
-		reader := bufio.NewReader(conn)
-		response, err = http.ReadResponse(reader, nil)
-		if err != nil {
-			fmt.Println("HTTP problem")
-			fmt.Println(err)
-			os.Exit(1)
-		}
-		io.Copy(os.Stdout, response.Body)
-		conn.Close()
-		if resume && iters == 2 {
-			fmt.Println("Attempting resumption")
-		}
-	}
-	os.Exit(0)
-}
diff --git a/_dev/tris-localserver/Dockerfile b/_dev/tris-localserver/Dockerfile
deleted file mode 100644
index 668b44d..0000000
--- a/_dev/tris-localserver/Dockerfile
+++ /dev/null
@@ -1,16 +0,0 @@
-FROM buildpack-deps
-
-ENV TLSDEBUG error
-
-EXPOSE 1443
-EXPOSE 2443
-EXPOSE 3443
-EXPOSE 4443
-EXPOSE 5443
-EXPOSE 6443
-EXPOSE 7443
-
-ADD tris-localserver /
-ADD runner.sh /
-
-CMD [ "./runner.sh" ]
diff --git a/_dev/tris-localserver/runner.sh b/_dev/tris-localserver/runner.sh
deleted file mode 100755
index 9b43013..0000000
--- a/_dev/tris-localserver/runner.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-./tris-localserver -b 0.0.0.0:1443 -cert=rsa   -rtt0=n  2>&1 &  # first port: ECDSA (and no 0-RTT)
-./tris-localserver -b 0.0.0.0:2443 -cert=ecdsa -rtt0=a  2>&1 &  # second port: RSA (and accept 0-RTT but not offer it)
-./tris-localserver -b 0.0.0.0:3443 -cert=ecdsa -rtt0=o  2>&1 &  # third port: offer and reject 0-RTT
-./tris-localserver -b 0.0.0.0:4443 -cert=ecdsa -rtt0=oa 2>&1 &  # fourth port: offer and accept 0-RTT
-./tris-localserver -b 0.0.0.0:5443 -cert=ecdsa -rtt0=oa -rtt0ack 2>&1 &  # fifth port: offer and accept 0-RTT but confirm
-./tris-localserver -b 0.0.0.0:6443 -cert=rsa   -cliauth 2>&1 &  # sixth port: RSA with required client authentication
-./tris-localserver -b 0.0.0.0:7443 -cert=ecdsa -pq=c &          # Enables support for both - post-quantum and classical KEX algorithms
-
-wait
diff --git a/_dev/tris-localserver/server.go b/_dev/tris-localserver/server.go
deleted file mode 100644
index 2e5a3f4..0000000
--- a/_dev/tris-localserver/server.go
+++ /dev/null
@@ -1,316 +0,0 @@
-package main
-
-import (
-	"crypto/x509"
-	"encoding/hex"
-	"errors"
-	"flag"
-	"fmt"
-	"github.com/henrydcase/trs"
-	"io/ioutil"
-	"log"
-	"net/http"
-	"os"
-	"strings"
-	"time"
-)
-
-type ZeroRTT_t int
-type PubKeyAlgo_t int
-
-// Bitset
-const (
-	ZeroRTT_None   ZeroRTT_t = 0
-	ZeroRTT_Offer            = 1 << 0
-	ZeroRTT_Accept           = 1 << 1
-)
-
-type server struct {
-	Address string
-	ZeroRTT ZeroRTT_t
-	TLS     tls.Config
-}
-
-var tlsVersionToName = map[uint16]string{
-	tls.VersionTLS10: "1.0",
-	tls.VersionTLS11: "1.1",
-	tls.VersionTLS12: "1.2",
-	tls.VersionTLS13: "1.3",
-}
-
-func NewServer() *server {
-	s := new(server)
-	s.ZeroRTT = ZeroRTT_None
-	s.Address = "0.0.0.0:443"
-	s.TLS = tls.Config{
-		GetConfigForClient: func(*tls.ClientHelloInfo) (*tls.Config, error) {
-			// If we send the first flight too fast, NSS sends empty early data.
-			time.Sleep(500 * time.Millisecond)
-			return nil, nil
-		},
-		MaxVersion: tls.VersionTLS13,
-		ClientAuth: tls.NoClientCert,
-	}
-
-	return s
-}
-
-func enablePQ(s *server, enableDefault bool) {
-	var pqGroups = []tls.CurveID{tls.HybridSIDHp503Curve25519, tls.HybridSIKEp503Curve25519}
-	if enableDefault {
-		var defaultCurvePreferences = []tls.CurveID{tls.X25519, tls.CurveP256, tls.CurveP384, tls.CurveP521}
-		s.TLS.CurvePreferences = append(s.TLS.CurvePreferences, defaultCurvePreferences...)
-	}
-	s.TLS.CurvePreferences = append(s.TLS.CurvePreferences, pqGroups...)
-}
-
-func (s *server) start() {
-	var err error
-	if (s.ZeroRTT & ZeroRTT_Offer) == ZeroRTT_Offer {
-		s.TLS.Max0RTTDataSize = 100 * 1024
-	}
-
-	if keyLogFile := os.Getenv("SSLKEYLOGFILE"); keyLogFile != "" {
-		s.TLS.KeyLogWriter, err = os.OpenFile(keyLogFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
-		if err != nil {
-			log.Fatalf("Cannot open keylog file: %v", err)
-		}
-		log.Println("Enabled keylog")
-	}
-
-	s.TLS.ClientCAs = x509.NewCertPool()
-	s.TLS.ClientCAs.AppendCertsFromPEM([]byte(rsaCa_client))
-	s.TLS.Accept0RTTData = ((s.ZeroRTT & ZeroRTT_Accept) == ZeroRTT_Accept)
-	s.TLS.NextProtos = []string{"npn_proto"}
-
-	httpServer := &http.Server{
-		Addr:      s.Address,
-		TLSConfig: &s.TLS,
-	}
-	log.Fatal(httpServer.ListenAndServeTLS("", ""))
-}
-
-// setServerCertificateFromArgs sets server certificate from an argument provided by the caller. Possible values
-// for arg_cert:
-// * "rsa": sets hardcoded RSA keypair
-// * "ecdsa": sets hardcoded ECDSA keypair
-// * FILE1:FILE2: Uses private key from FILE1 and public key from FILE2. Both must be in PEM format. FILE2 can
-//   be single certificate or certificate chain.
-// * nil: fallbacks to "rsa"
-//
-// Function generate a panic in case certificate can't be correctly set
-func (s *server) setServerCertificateFromArgs(arg_cert *string) {
-	var certStr, keyStr []byte
-	var cert tls.Certificate
-	var err error
-
-	if arg_cert == nil {
-		// set rsa by default
-		certStr, keyStr = []byte(rsaCert), []byte(rsaKey)
-	} else {
-		switch *arg_cert {
-		case "rsa":
-			certStr, keyStr = []byte(rsaCert), []byte(rsaKey)
-		case "ecdsa":
-			certStr, keyStr = []byte(ecdsaCert), []byte(ecdsaKey)
-		default:
-			files := strings.Split(*arg_cert, ":")
-			if len(files) != 2 {
-				err = errors.New("Wrong format provided after -cert.")
-				goto err
-			}
-			keyStr, err = ioutil.ReadFile(files[0])
-			if err != nil {
-				goto err
-			}
-			certStr, err = ioutil.ReadFile(files[1])
-			if err != nil {
-				goto err
-			}
-		}
-	}
-
-	cert, err = tls.X509KeyPair(certStr, keyStr)
-	if err != nil {
-		goto err
-	}
-
-	s.TLS.Certificates = []tls.Certificate{cert}
-err:
-	if err != nil {
-		// Not possible to proceed really
-		log.Fatal(err)
-		panic(err)
-	}
-}
-
-func main() {
-
-	s := NewServer()
-
-	arg_addr := flag.String("b", "0.0.0.0:443", "Address:port used for binding")
-	arg_cert := flag.String("cert", "rsa", "Public algorithm to use:\nOptions [rsa, ecdsa, PrivateKeyFile:CertificateChainFile]")
-	arg_zerortt := flag.String("rtt0", "n", `0-RTT, accepts following values [n: None, a: Accept, o: Offer, oa: Offer and Accept]`)
-	arg_confirm := flag.Bool("rtt0ack", false, "0-RTT confirm")
-	arg_clientauth := flag.Bool("cliauth", false, "Performs client authentication (RequireAndVerifyClientCert used)")
-	arg_pq := flag.String("pq", "", "Enable quantum-resistant algorithms [c: Support classical and Quantum-Resistant, q: Enable Quantum-Resistant only]")
-	flag.Parse()
-
-	s.Address = *arg_addr
-
-	s.setServerCertificateFromArgs(arg_cert)
-
-	if *arg_zerortt == "a" {
-		s.ZeroRTT = ZeroRTT_Accept
-	} else if *arg_zerortt == "o" {
-		s.ZeroRTT = ZeroRTT_Offer
-	} else if *arg_zerortt == "oa" {
-		s.ZeroRTT = ZeroRTT_Offer | ZeroRTT_Accept
-	}
-
-	if *arg_clientauth {
-		s.TLS.ClientAuth = tls.RequireAndVerifyClientCert
-	}
-
-	if *arg_pq == "c" {
-		enablePQ(s, true)
-	} else if *arg_pq == "q" {
-		enablePQ(s, false)
-	}
-
-	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
-		tlsConn := r.Context().Value(http.TLSConnContextKey).(*tls.Conn)
-
-		with0RTT := ""
-		if !tlsConn.ConnectionState().HandshakeConfirmed {
-			with0RTT = " [0-RTT]"
-		}
-		if *arg_confirm || r.URL.Path == "/confirm" {
-			if err := tlsConn.ConfirmHandshake(); err != nil {
-				log.Fatal(err)
-			}
-			if with0RTT != "" {
-				with0RTT = " [0-RTT confirmed]"
-			}
-			if !tlsConn.ConnectionState().HandshakeConfirmed {
-				panic("HandshakeConfirmed false after ConfirmHandshake")
-			}
-		}
-
-		resumed := ""
-		if r.TLS.DidResume {
-			resumed = " [resumed]"
-		}
-
-		http2 := ""
-		if r.ProtoMajor == 2 {
-			http2 = " [HTTP/2]"
-		}
-
-		fmt.Fprintf(w, "

Hello TLS %s%s%s%s _o/\n", tlsVersionToName[r.TLS.Version], resumed, with0RTT, http2) - }) - - http.HandleFunc("/ch", func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "text/plain") - fmt.Fprintf(w, "Client Hello packet (%d bytes):\n%s", len(r.TLS.ClientHello), hex.Dump(r.TLS.ClientHello)) - }) - - s.start() -} - -const ( - rsaKey = `-----BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEA1DHcIM3SThFqy8nAkPQFX0E7ph8jqh8EATXryjKHGuVjR3Xh -OQ0BSPoJxyfdg/VEwevFrtmZAfz0WCbxvP2SVCmf7oobg4V2KPSo3nNt9vlBFUne -RtIyHRQ8YRnGSWaRHzJbX6ffltnG2aD+8qUfk161rdZgxBA9G0Ga47IkwQhT2Hqu -H3dW2Uu4W2WMyt6gX/tdyEAV57MOPcoceknr7Nb2kfiuDPR7h6wFrW3I6eoj8oX2 -SkIOuVNt1Z31BAUcPJDUjqopI0o9tolM/7X13M8dEY0OJQVr7FQYDF9JeSYeEMyb -wizjBaHDm48mSghP1o5UssQBbNNC83btXCjiLQIDAQABAoIBACzvGgRAUYaCnbDl -2kdXxUN0luMIuQ6vXrO67WF17bI+XRWm2riwDlObzzJDON9Wsua1vLjYD1SickOw -i4RP1grIfbuPt1/UhT8LAC+LFgA0rBmL+OvaWw5ZWKffQ2QLujN3AG5zKB/Tog43 -z4UmfldAuQxE11zta2M4M0qAUNQnQj1oiuI8RUdG0VvvLw8Htdi1ogH0CI5R669z -NjHt+JV+2gzKx6EX0s8mQL3yXGkC2xXItRbFclyCMJEhPS7QbBu+tru35N6WpzAq -BCl2Q7LQogvSA6MXuMOx6CyuExVfgmhbfeoheLE8gmXwl0Y37n/g6ZBZFAtpCjcs -UckPv0ECgYEA1orl7RwgIsZljMap6vWtMGoRIHKmT91DGpMmkh4suZe+yAk85maU -49Vd+8ZfIN41AH37yrsGOcPHgz5o5QufELpoub6DCsQ7u9F1vQp55cp+qyBWzAgz -b/xUuVnIyv3kLan3fpk7ZGCBXFBpLG0QXMFOHtda3Mlk5SmuoEYaYRkCgYEA/TLR -u4neKqyqwsqMuRJGC1iKFVmfCjZeNMtPNbTWpdqez/vvT8APnEpIumUGt8YROLGZ -8biUr5/ViOkmaP3wmQbO9m2/cE01lMTYv75w1cw2KVQe6kAHJkOx+JEx9xg53RJ/ -QlFtG5MQUy2599Gxp8BMGaXLH5yo4qwvNvY6CDUCgYEArxr7AwX7rKZlZ/sV4HHY -gzVu+R7aY0DibiRATO5X7rrNuhLgI+UCDNqvNLn6FqeGdvpcsmDneeozQwmDL77G -ey7KHyBBcF4tquQQxtRwHX+i1yUz8p+W7AX1WLrRSezjeenJ2QhUE1849hGjZeE2 -g546lq2Kub2enfPhVWsiSLECgYEA72T5QCPeVuLioUH5Q5Kvf1K7W+xcnr9A2xHP -Vqwgtre5qFQ/tFuXZuIlWXbjnyY6aiwhrZYjntm0f7pRgrt2nHj/fafOdVPK8Voc -xU4+SSbHntPWVw0qtVcUEjzVzRauvwMaJ43tZ0DpEnwNdO5i1oTObwF+x+jLFWZP -TdwIinECgYBzjZeCxxOMk5SlPpTsLUtgC+q3m1AavXhUVNEPP2gKMOIPTETPbhbG -LBxB2vVbJiS3J7itQy8gceT89O0vSEZnaTPXiM/Ws1QbkBJ8yW7KI7X4WuzN4Imq -/cLBRXLb8R328U27YyQFNGMjr2tX/+vx5FulJjSloWMRNuFWUngv7w== ------END RSA PRIVATE KEY-----` - rsaCert = `-----BEGIN CERTIFICATE----- -MIIC+jCCAeKgAwIBAgIRANBDimJ/ww2tz77qcYIhuZowDQYJKoZIhvcNAQELBQAw -EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xNjA5MjQxNzI5MTlaFw0yNjA5MjIxNzI5 -MTlaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQDUMdwgzdJOEWrLycCQ9AVfQTumHyOqHwQBNevKMoca5WNHdeE5DQFI -+gnHJ92D9UTB68Wu2ZkB/PRYJvG8/ZJUKZ/uihuDhXYo9Kjec232+UEVSd5G0jId -FDxhGcZJZpEfMltfp9+W2cbZoP7ypR+TXrWt1mDEED0bQZrjsiTBCFPYeq4fd1bZ -S7hbZYzK3qBf+13IQBXnsw49yhx6Sevs1vaR+K4M9HuHrAWtbcjp6iPyhfZKQg65 -U23VnfUEBRw8kNSOqikjSj22iUz/tfXczx0RjQ4lBWvsVBgMX0l5Jh4QzJvCLOMF -ocObjyZKCE/WjlSyxAFs00Lzdu1cKOItAgMBAAGjSzBJMA4GA1UdDwEB/wQEAwIF -oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBQGA1UdEQQNMAuC -CWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEAygPV4enmvwSuMd1JarxOXpOK -Z4Nsk7EKlfCPgzxQUOkFdLIr5ZG1kUkQt/omzTmoIWjLAsoYzT0ZCPOrioczKsWj -MceFUIkT0w+eIl+8DzauPy34o8rjcApglF165UG3iphlpI+jdPzv5TBarUAbwsFb -ClMLEiNJQ0OMxAIaRtb2RehD4q3OWlpWf6joJ36PRBqL8T5+f2x6Tg3c64UR+QPX -98UcCQHHdEhm7y2z5Z2Wt0B48tZ+UAxDEoEwMghNyw7wUD79IRlXGYypBnXaMuLX -46aGxbsSQ7Rfg62Co3JG7vo+eJd0AoZHrtFUnfM8V70IFzMBZnSwRslHRJe56Q== ------END CERTIFICATE-----` - rsaCa_client = `-----BEGIN CERTIFICATE----- -MIIF6zCCA9OgAwIBAgIUC4U4HlbkVMrKKTFK0mNrMFDpRskwDQYJKoZIhvcNAQEL -BQAwfTELMAkGA1UEBhMCRlIxDTALBgNVBAgMBFBBQ0ExFzAVBgNVBAcMDkNhZ25l -cyBzdXIgTWVyMSIwIAYDVQQLDBlDZXJ0IFRlc3RpbmcgT3JnYW5pemF0aW9uMSIw -IAYDVQQDDBlDZXJ0IFRlc3RpbmcgT3JnYW5pemF0aW9uMB4XDTE5MDIyMjAwNDIz -OVoXDTQ2MDcwOTAwNDIzOVowfTELMAkGA1UEBhMCRlIxDTALBgNVBAgMBFBBQ0Ex -FzAVBgNVBAcMDkNhZ25lcyBzdXIgTWVyMSIwIAYDVQQLDBlDZXJ0IFRlc3Rpbmcg -T3JnYW5pemF0aW9uMSIwIAYDVQQDDBlDZXJ0IFRlc3RpbmcgT3JnYW5pemF0aW9u -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0z+DMLb7YIMFFNZpn+ve -NdT7GL9DPyV9ZWSHpUuDyme6Og6Mp5IpCLlKjNXtizX5aQ9xQ746slt70fivSV/r -tiEtayZkcwS7zHtc5f+U/S0hR1q5Zh3DaLQH9diSeuNFQN5pg7zQT5csJFlxf6EB -j/ioSBC+J1E8A2FAh0qDq+TvPPyZEEjcJy0oBuNHUnkC3rwjt24DAUI26rN/Qk9P -a6KR9bBOdHFFul3DEP/uPqWV9TvV5tJhP3J2RbfS79WljFy/lFIwvJvfQHYEjMt4 -/gq8yTSUgJ8zmgJQ1sgOKH1FzJd4EdAMquSYbElkc35jX8gggUNOUcwsIfJBnu41 -SC51JQruNT256zse76o8Dx3lSHiz5c6luZyJnZWWt6xWtfGEGMnckpn6cVvcbbgq -eWqmttgE2QTpgYoYUVcX/XFtsmZVTu05r8MZoqje5rgW9nEvvW+3M+eT5h0M9eGQ -bIT3D3tdXB2XWCjUWqxpZscFwyumGu7vdykBKLhMVR3nEpFfORnH+534vwi49fjz -WnN6fXAZZLPnGtEdWXNgs9JtgI5UheAQbcA3FT+M3maa88V2JrETLps405NYp6hJ -6msbS/AmV/eSilRmbGVj9TfKHb/BVHNYwVQ0Bu/QN2YQNQ9olOpIxXgKr6Y4tKZt -wTOMiCxZrnDQneQOTnW0NAMCAwEAAaNjMGEwHQYDVR0OBBYEFNLiS6YezH2bWiZ3 -TNbkQzMoBBB2MB8GA1UdIwQYMBaAFNLiS6YezH2bWiZ3TNbkQzMoBBB2MA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQAQ -cWIFOusSLKizqcqMsbMIY/Jzy0Tq5jzeOAQEQBztu7eJb208SG2EJtD6ylBQCF8t -FCxUbvWNrly1MJoMSXdn3uMz3kLKNQa6RENckwA1UuYZpdhvTUtmPun9QqFPJdqm -oi0paOVut9q3dplDy6MUknGN4tNWp2ZDfyvom3mUMfYGEO/FCWTy8eFd6cHRE9bw -tHkcX5r7GpDHH5vKXOF/deMp1Xgep5ZTasL13YwPiYgctst91pEfdcztjHW0mQNT -ZH/TUQDgs2UCjcvyeOlgoZixWOpkf1Qyje15k9qMb89/5hdarxvAQbG2BezQtzyk -bbCu1MQa2DBdAKbhQxas/DPSvSkA/y8v+hiovTWtPKErPnQqZqVy59KUTBWj8ZAj -5dkDVjBvUcsJ/6zHv0X9puEnIDZ8pK+Xn9LbcbPE7Nf1ikDyOqHmLmhGfWlEGvoD -3Q8f8zUySZ40mfqtVhc7OYqA66Q9quNQ4VBESVNiEJ/LuWHRXe74KqFdggsQqtS6 -UQQgw5lFnKHZ9pk2VlKzgpkmd5fLMOhcHWQbsah9TFOuW5vEhWGHNhGCyGouWTzD -mkwlPS8arj/ymUn6t/oiwSOA6GbjQLnTXvoAjdBxnukQlNY6TUDk+lSQw0qfZGIA -xZywUgRbLZH8TFUnuEQps35XnWrY8rrXVj9+9h0B4g== ------END CERTIFICATE-----` - ecdsaCert = `-----BEGIN CERTIFICATE----- -MIIBbTCCAROgAwIBAgIQZCsHZcs5ZkzV+zC2E6j5RzAKBggqhkjOPQQDAjASMRAw -DgYDVQQKEwdBY21lIENvMB4XDTE2MDkyNDE3NTE1OFoXDTI2MDkyMjE3NTE1OFow -EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDTO -B3IyzjYfKCp2HWy+P3QHxhdBT4AUGYgwTiSEj5phumPIahFNcOSWptN0UzlZvJdN -MMjVmrFYK/FjF4abkNKjSzBJMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggr -BgEFBQcDATAMBgNVHRMBAf8EAjAAMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAKBggq -hkjOPQQDAgNIADBFAiEAp9W157PM1IadPBc33Cbj7vaFvp+rXs/hSuMCzP8pgV8C -IHCswo1qiC0ZjQmWsBlmz5Zbp9rOorIzBYmGRhRdNs3j ------END CERTIFICATE-----` - ecdsaKey = `-----BEGIN EC PRIVATE KEY----- -MHcCAQEEIFdhO7IW5UIwpB1e2Vunm9QyKvUHWcVwGfLjhpOajuR7oAoGCCqGSM49 -AwEHoUQDQgAENM4HcjLONh8oKnYdbL4/dAfGF0FPgBQZiDBOJISPmmG6Y8hqEU1w -5Jam03RTOVm8l00wyNWasVgr8WMXhpuQ0g== ------END EC PRIVATE KEY-----` -) diff --git a/_dev/tris-localserver/start.sh b/_dev/tris-localserver/start.sh deleted file mode 100755 index 4e31048..0000000 --- a/_dev/tris-localserver/start.sh +++ /dev/null @@ -1,5 +0,0 @@ -#! /bin/sh -set -e - -exec docker run --name tris-localserver --env TLSDEBUG=error "$@" tris-localserver - diff --git a/_dev/tris-testclient/Dockerfile b/_dev/tris-testclient/Dockerfile deleted file mode 100644 index 8e9e050..0000000 --- a/_dev/tris-testclient/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM buildpack-deps - -ENV TLSDEBUG error - -ADD tris-testclient / - -ENTRYPOINT ["/tris-testclient"] diff --git a/_dev/tris-testclient/client.go b/_dev/tris-testclient/client.go deleted file mode 100644 index d642acc..0000000 --- a/_dev/tris-testclient/client.go +++ /dev/null @@ -1,303 +0,0 @@ -package main - -import ( - "crypto/x509" - "errors" - "flag" - "fmt" - "github.com/henrydcase/trs" - "io" - "log" - "os" - "strings" -) - -var tlsVersionToName = map[uint16]string{ - tls.VersionTLS10: "1.0", - tls.VersionTLS11: "1.1", - tls.VersionTLS12: "1.2", - tls.VersionTLS13: "1.3", -} - -var cipherSuiteIdToName = map[uint16]string{ - tls.TLS_RSA_WITH_AES_128_CBC_SHA: "TLS_RSA_WITH_AES_128_CBC_SHA", - tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", - tls.TLS_AES_128_GCM_SHA256: "TLS_AES_128_GCM_SHA256", - tls.TLS_AES_256_GCM_SHA384: "TLS_AES_256_GCM_SHA384", - tls.TLS_CHACHA20_POLY1305_SHA256: "TLS_CHACHA20_POLY1305_SHA256", -} - -var namedGroupsToName = map[uint16]string{ - uint16(tls.HybridSIDHp503Curve25519): "X25519-SIDHp503", - uint16(tls.HybridSIKEp503Curve25519): "X25519-SIKEp503", - uint16(tls.X25519): "X25519", - uint16(tls.CurveP256): "P-256", - uint16(tls.CurveP384): "P-384", - uint16(tls.CurveP521): "P-521", -} - -func getIDByName(m map[uint16]string, name string) (uint16, error) { - for key, value := range m { - if value == name { - return key, nil - } - } - return 0, errors.New("Unknown value") -} - -var failed uint - -type Client struct { - TLS tls.Config - addr string -} - -func NewClient() *Client { - var c Client - c.TLS.InsecureSkipVerify = true - return &c -} - -func (c *Client) clone() *Client { - var clone Client - clone.TLS = *c.TLS.Clone() - clone.addr = c.addr - return &clone -} - -func (c *Client) setMinMaxTLS(ver uint16) { - c.TLS.MinVersion = ver - c.TLS.MaxVersion = ver -} - -func (c *Client) run() { - fmt.Printf("TLS %s with %s\n", tlsVersionToName[c.TLS.MinVersion], cipherSuiteIdToName[c.TLS.CipherSuites[0]]) - - con, err := tls.Dial("tcp", c.addr, &c.TLS) - if err != nil { - fmt.Printf("handshake failed: %v\n\n", err) - failed++ - return - } - defer con.Close() - - _, err = con.Write([]byte("GET / HTTP/1.1\r\nHost: localhost\r\n\r\n")) - if err != nil { - fmt.Printf("Write failed: %v\n\n", err) - failed++ - return - } - - buf := make([]byte, 1024) - n, err := con.Read(buf) - // A non-zero read with EOF is acceptable and occurs when a close_notify - // is received right after reading data (observed with NSS selfserv). - if !(n > 0 && err == io.EOF) && err != nil { - fmt.Printf("Read failed: %v\n\n", err) - failed++ - return - } - fmt.Printf("[TLS: %s] Read %d bytes\n", tlsVersionToName[con.ConnectionState().Version], n) - fmt.Println("OK\n") -} - -func result() { - if failed > 0 { - log.Fatalf("Failed handshakes: %d\n", failed) - } else { - fmt.Println("All handshakes passed") - } -} - -// Usage client args host:port -func main() { - var keylog_file, tls_version, named_groups, named_ciphers string - var enable_rsa, enable_ecdsa, client_auth bool - - flag.StringVar(&keylog_file, "keylogfile", "", "Secrets will be logged here") - flag.BoolVar(&enable_rsa, "rsa", true, "Whether to enable RSA cipher suites") - flag.BoolVar(&enable_ecdsa, "ecdsa", true, "Whether to enable ECDSA cipher suites") - flag.BoolVar(&client_auth, "cliauth", false, "Whether to enable client authentication") - flag.StringVar(&tls_version, "tls_version", "1.3", "TLS version to use") - flag.StringVar(&named_groups, "groups", "X25519:P-256:P-384:P-521", "NamedGroups IDs to use") - flag.StringVar(&named_ciphers, "ciphers", "TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384", "Named cipher IDs to use") - flag.Parse() - if flag.NArg() != 1 { - flag.Usage() - os.Exit(1) - } - - client := NewClient() - client.addr = flag.Arg(0) - if !strings.Contains(client.addr, ":") { - client.addr += ":443" - } - - if keylog_file == "" { - keylog_file = os.Getenv("SSLKEYLOGFILE") - } - if keylog_file != "" { - keylog_writer, err := os.OpenFile(keylog_file, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600) - if err != nil { - log.Fatalf("Cannot open keylog file: %v", err) - } - client.TLS.KeyLogWriter = keylog_writer - log.Println("Enabled keylog") - } - - if client_auth { - var err error - client_cert, err := tls.X509KeyPair([]byte(client_crt), []byte(client_key)) - if err != nil { - panic("Can't load client certificate") - } - - client.TLS.Certificates = []tls.Certificate{client_cert} - client.TLS.RootCAs = x509.NewCertPool() - if !client.TLS.RootCAs.AppendCertsFromPEM([]byte(client_ca)) { - panic("Can't load client CA cert") - } - } - - if enable_rsa { - // Sanity check: TLS 1.2 with the mandatory cipher suite from RFC 5246 - c := client.clone() - c.TLS.CipherSuites = []uint16{tls.TLS_RSA_WITH_AES_128_CBC_SHA} - c.setMinMaxTLS(tls.VersionTLS12) - c.run() - } - - if enable_ecdsa { - // Sane cipher suite for TLS 1.2 with an ECDSA cert (as used by boringssl) - c := client.clone() - c.TLS.CipherSuites = []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256} - c.setMinMaxTLS(tls.VersionTLS12) - c.run() - } - - // Set requested DH groups - client.TLS.CurvePreferences = []tls.CurveID{} - for _, ng := range strings.Split(named_groups, ":") { - id, err := getIDByName(namedGroupsToName, ng) - if err != nil { - panic("Wrong group name provided") - } - client.TLS.CurvePreferences = append(client.TLS.CurvePreferences, tls.CurveID(id)) - } - - // Perform TLS handshake with each each requested CipherSuite - tlsID, err := getIDByName(tlsVersionToName, tls_version) - if err != nil { - panic("Unknown TLS version") - } - for _, cn := range strings.Split(named_ciphers, ":") { - id, err := getIDByName(cipherSuiteIdToName, cn) - if err != nil { - panic("Wrong cipher name provided") - } - client.setMinMaxTLS(tlsID) - client.TLS.CipherSuites = []uint16{id} - client.run() - } - - // TODO test other kex methods besides X25519, like MTI secp256r1 - // TODO limit supported groups? - - result() -} - -const ( - client_ca = `-----BEGIN CERTIFICATE----- -MIIF6zCCA9OgAwIBAgIUC4U4HlbkVMrKKTFK0mNrMFDpRskwDQYJKoZIhvcNAQEL -BQAwfTELMAkGA1UEBhMCRlIxDTALBgNVBAgMBFBBQ0ExFzAVBgNVBAcMDkNhZ25l -cyBzdXIgTWVyMSIwIAYDVQQLDBlDZXJ0IFRlc3RpbmcgT3JnYW5pemF0aW9uMSIw -IAYDVQQDDBlDZXJ0IFRlc3RpbmcgT3JnYW5pemF0aW9uMB4XDTE5MDIyMjAwNDIz -OVoXDTQ2MDcwOTAwNDIzOVowfTELMAkGA1UEBhMCRlIxDTALBgNVBAgMBFBBQ0Ex -FzAVBgNVBAcMDkNhZ25lcyBzdXIgTWVyMSIwIAYDVQQLDBlDZXJ0IFRlc3Rpbmcg -T3JnYW5pemF0aW9uMSIwIAYDVQQDDBlDZXJ0IFRlc3RpbmcgT3JnYW5pemF0aW9u -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0z+DMLb7YIMFFNZpn+ve -NdT7GL9DPyV9ZWSHpUuDyme6Og6Mp5IpCLlKjNXtizX5aQ9xQ746slt70fivSV/r -tiEtayZkcwS7zHtc5f+U/S0hR1q5Zh3DaLQH9diSeuNFQN5pg7zQT5csJFlxf6EB -j/ioSBC+J1E8A2FAh0qDq+TvPPyZEEjcJy0oBuNHUnkC3rwjt24DAUI26rN/Qk9P -a6KR9bBOdHFFul3DEP/uPqWV9TvV5tJhP3J2RbfS79WljFy/lFIwvJvfQHYEjMt4 -/gq8yTSUgJ8zmgJQ1sgOKH1FzJd4EdAMquSYbElkc35jX8gggUNOUcwsIfJBnu41 -SC51JQruNT256zse76o8Dx3lSHiz5c6luZyJnZWWt6xWtfGEGMnckpn6cVvcbbgq -eWqmttgE2QTpgYoYUVcX/XFtsmZVTu05r8MZoqje5rgW9nEvvW+3M+eT5h0M9eGQ -bIT3D3tdXB2XWCjUWqxpZscFwyumGu7vdykBKLhMVR3nEpFfORnH+534vwi49fjz -WnN6fXAZZLPnGtEdWXNgs9JtgI5UheAQbcA3FT+M3maa88V2JrETLps405NYp6hJ -6msbS/AmV/eSilRmbGVj9TfKHb/BVHNYwVQ0Bu/QN2YQNQ9olOpIxXgKr6Y4tKZt -wTOMiCxZrnDQneQOTnW0NAMCAwEAAaNjMGEwHQYDVR0OBBYEFNLiS6YezH2bWiZ3 -TNbkQzMoBBB2MB8GA1UdIwQYMBaAFNLiS6YezH2bWiZ3TNbkQzMoBBB2MA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQAQ -cWIFOusSLKizqcqMsbMIY/Jzy0Tq5jzeOAQEQBztu7eJb208SG2EJtD6ylBQCF8t -FCxUbvWNrly1MJoMSXdn3uMz3kLKNQa6RENckwA1UuYZpdhvTUtmPun9QqFPJdqm -oi0paOVut9q3dplDy6MUknGN4tNWp2ZDfyvom3mUMfYGEO/FCWTy8eFd6cHRE9bw -tHkcX5r7GpDHH5vKXOF/deMp1Xgep5ZTasL13YwPiYgctst91pEfdcztjHW0mQNT -ZH/TUQDgs2UCjcvyeOlgoZixWOpkf1Qyje15k9qMb89/5hdarxvAQbG2BezQtzyk -bbCu1MQa2DBdAKbhQxas/DPSvSkA/y8v+hiovTWtPKErPnQqZqVy59KUTBWj8ZAj -5dkDVjBvUcsJ/6zHv0X9puEnIDZ8pK+Xn9LbcbPE7Nf1ikDyOqHmLmhGfWlEGvoD -3Q8f8zUySZ40mfqtVhc7OYqA66Q9quNQ4VBESVNiEJ/LuWHRXe74KqFdggsQqtS6 -UQQgw5lFnKHZ9pk2VlKzgpkmd5fLMOhcHWQbsah9TFOuW5vEhWGHNhGCyGouWTzD -mkwlPS8arj/ymUn6t/oiwSOA6GbjQLnTXvoAjdBxnukQlNY6TUDk+lSQw0qfZGIA -xZywUgRbLZH8TFUnuEQps35XnWrY8rrXVj9+9h0B4g== ------END CERTIFICATE-----` - client_crt = `-----BEGIN CERTIFICATE----- -MIIFSjCCAzKgAwIBAgIUCKk2npLYEX2Z3Ceu1CwSKK50j04wDQYJKoZIhvcNAQEL -BQAwfTELMAkGA1UEBhMCRlIxDTALBgNVBAgMBFBBQ0ExFzAVBgNVBAcMDkNhZ25l -cyBzdXIgTWVyMSIwIAYDVQQLDBlDZXJ0IFRlc3RpbmcgT3JnYW5pemF0aW9uMSIw -IAYDVQQDDBlDZXJ0IFRlc3RpbmcgT3JnYW5pemF0aW9uMB4XDTE5MDIyMjAwNDMz -MloXDTQ2MDcwOTAwNDMzMlowfTELMAkGA1UEBhMCRlIxDTALBgNVBAgMBFBBQ0Ex -FzAVBgNVBAcMDkNhZ25lcyBzdXIgTWVyMSIwIAYDVQQLDBlDZXJ0IFRlc3Rpbmcg -T3JnYW5pemF0aW9uMSIwIAYDVQQDDBlDZXJ0IFRlc3RpbmcgT3JnYW5pemF0aW9u -MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEA0DQrWlCfijylutz28aTB -T9WDnvBWpJ535t/Clt4o2nv3Cp6JxvUVzYkdKuaLR295gyEBx9JSHiZxPiJoPVfp -wigmG0R9HvByAG5rhaQbQt99npoBaHMps1i12VxxFy1yaqZW6mrwrHMfV716rZ2M -AzWx7UfhutloBYeeluiziDWUSEuGeJG7kHdvUtGYlbRd/ElFWHOfAQ7Oc8UUjEHW -sorkqciqyAERV/H9hr5Rap/J/ERcFC8bNecS4t1Yh98WgIun/MbcBKQzo1LsWmOQ -dmaMBoG8g1mYRbNap8G/+aQbjfRi1zN0yaW1wtlLoBJmNgLjwYgaS/5Uey5NZMdb -NwIBA6OBwzCBwDAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAxBglghkgB -hvhCAQ0EJBYiQ2VydCBUZXN0aW5nIEludGVybWVkaWF0ZSAtIENsaWVudDAdBgNV -HQ4EFgQULlrGFPbxwz525ywQYPs72P7YnL4wHwYDVR0jBBgwFoAU0uJLph7MfZta -JndM1uRDMygEEHYwDgYDVR0PAQH/BAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUFBwMC -BggrBgEFBQcDBDANBgkqhkiG9w0BAQsFAAOCAgEAwLc+Xg5Fyfbgu5iFs1y7E0Et -4E/5lF0A4iqDVX3e7/upoUIBFZFv2PlAqIlhQ49NgGlIfrBlwEijZJ9kgVmUcKDS -UrqBvKUn+99dTC8Zn/Py9ofLNcJy+qNJg4TpbpBxXaP1MXdZYXdYkGtyyPIGo31U -oHibNLQDCtKFMoEPCvFuCBtJgyT46l5KN7VQCA0ZDm84fVmIgEEOXWwz0mDIhGWm -hDhmqONznl0+aHirqJxsBaplBaFVV1N02ksR53sPPy/UfDsAD3Fpp8R1DAMEyy0o -kTqm8QINVL961YT1Y/oI+GlypjPq9cL0dEHdxwu6gyCHPMMGGGIDHmLoqJJuj/Kr -/T08jhtDv8D7e9m3wfSW/RqHKE31Yy21SXv/gpcHGunwzDoj/QUvRl/xTjJfx+S8 -2NHxSU8QOdexhJumsNFJe8kH8cRJMCMB8/hfiBpI0QANkUBJ1aaa/p7vZuEKJm+/ -85m3Yz+zn58/Bube06z6QzFeR8Edi+6hXk4/WoHltgXiNowD3d4xI48sPWEbe+QZ -6u60sEdpY2a+3Xwt9m9R2R+sGP3QyDFd9GVaUPt21TeeLdfS3kPqwO2k+UXB8nV3 -Yh1Hvyx67u0tX3wBVe40CNaAu7iW+e4aXjksG2dxk71lNq5CHJCOtbRK4LUArjy5 -cw4KAXWoaR8YIC3BWgg= ------END CERTIFICATE-----` - client_key = `-----BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDQNCtaUJ+KPKW6 -3PbxpMFP1YOe8Faknnfm38KW3ijae/cKnonG9RXNiR0q5otHb3mDIQHH0lIeJnE+ -Img9V+nCKCYbRH0e8HIAbmuFpBtC332emgFocymzWLXZXHEXLXJqplbqavCscx9X -vXqtnYwDNbHtR+G62WgFh56W6LOINZRIS4Z4kbuQd29S0ZiVtF38SUVYc58BDs5z -xRSMQdayiuSpyKrIARFX8f2GvlFqn8n8RFwULxs15xLi3ViH3xaAi6f8xtwEpDOj -UuxaY5B2ZowGgbyDWZhFs1qnwb/5pBuN9GLXM3TJpbXC2UugEmY2AuPBiBpL/lR7 -Lk1kx1s3AgEDAoIBAQCKzXI8Nb+xfcPR6KShGIDf460UoDnDFE/vP9cPPsXm/U9c -abEvTg6JBhNx7weE9PuswKvajDa+xEt+wZrTj/EsGsQSLai/Svaq9EeubWeB6lO/ -EVZFohvM5c6Q6EtkyPbxxDnxnKBy92o6flHJE7KsznaeL+vR5kVZBRRkmyJazS4s -Z5rbrN9AhSIfyHs9GCQGgsXT6HMsyoJYFastwQ2qj+9L2ypcM8TW+KGzGfJipoJb -l/N/8WHb4ZumA67lfWq4v5JTA5qAUKcfPszEBrUfQ34Tk+73Iiov9f7SXPYxWxVJ -g9PuzfewvJrp6CPv+/mKNt8PmBYkaXlnyjr9tCwLAoGBAPjAVZapQVuIqftcOZtf -Re9fAV9Vvv1FEO8bKJeIsPDlRkdg+TfTMgxhZU0I3P4XdEj7Fa87w4wkA6GkIrOO -W9/usPOYzSdTP5aVEsdGbT8yD2vTST7Aw/GESKTRJA/Fe1PIb5Nz3OijyTusvFE+ -XSR3EXb1myX+2rFS0Wbiz2U5AoGBANZFWoeFzREnBcDG60RayjiTg71E1/T4zhvU -e/w+71FNbLZXBrNqgV20F73xOme/Mb13yr+YgXxIEQfFtR6hRxZ8u1jndEzw66Jf -YfHt7EGVceMV2pdP4md5ebebEj7qICfXPxF9IZicwZG3QMR5u0tvnx40iNMWhW0M -rY4FabPvAoGBAKXVjmRw1j0FxqeS0RI/g/TqAOo5Kf4uC0oSGw+wdfXuLtpApiU3 -drLrmN4F6Klk+DCnY8on17LCrRZtbHe0PT/0dfe7M2+M1Q8ODITZniohX503hinV -1/ZYMG3gwrUuUjfa9Qz36JsX230d0uDUPhhPYPn5EhlUkcuMi5nsikN7AoGBAI7Y -5wUD3gtvWSsvR4LnMXsNAn4t5U37NBKNp/1/SjYznc7kryJHAOkiun6g0Zp/dn5P -3H+7AP2FYK/ZI2nA2g790jtE+DNLR8GU6/aenYEOS+y5PGTf7ET7pnpnYX9GwBqP -f2D+FmW91mEk1dhRJ4efv2l4WzdkWPNdyQlY8SKfAoGAEIWmowo7EpbR5Boxc2o3 -Tl0JbGi1CNJAHtDjEJCd1OxKrMUrK07hOeEKF6y8K/WBuQhFvI2pu16oT4sMal9Z -mEiJdJAFErefPLQGomHLXfq9mDEY13Ug/xAd9aMyYcubIg5XjAqLMrB60HcrLr7Q -2hMCSDdVP2V/F3QVh8DEirE= ------END PRIVATE KEY-----` -) diff --git a/_dev/tstclnt/Dockerfile b/_dev/tstclnt/Dockerfile deleted file mode 100644 index e51e724..0000000 --- a/_dev/tstclnt/Dockerfile +++ /dev/null @@ -1,61 +0,0 @@ -FROM buildpack-deps - -RUN hg clone https://hg.mozilla.org/projects/nspr -RUN hg clone https://hg.mozilla.org/projects/nss - -ENV USE_64=1 NSS_ENABLE_TLS_1_3=1 -# Incremental build snapshot disabled as dependencies don't seem to be solid: -# the same value changed in a header file would apply to one .c file and not another -# RUN cd nss && make nss_build_all - -# Draft 15 -# ARG REVISION=c483e5f9e0bc - -# Draft 16 -# ARG REVISION=3e7b53b18112 - -# Draft 18 -# ARG REVISION=b6dfef6d0ff0 - -# Draft 18, NSS_3_34_1_RTM (with TLS 1.3 keylogging support) -# ARG REVISION=e61c0f657100 - -# Draft 22 -#ARG REVISION=88c3f3fa581b - -# Draft 23 -# ARG REVISION=16c622c9e1cc - -# Latest -ARG REVISION=ee357b00f2e6 - -RUN cd nss && hg pull -RUN cd nss && hg checkout -C $REVISION - -ADD *.patch ./ -RUN for p in *.patch; do patch -p1 -d nss < $p; done - -RUN cd nss && make nss_build_all - -# ENV HOST=localhost -# RUN cd nss/tests/ssl_gtests && ./ssl_gtests.sh - -RUN cd nss && make install - -RUN mv /dist/$(uname -s)$(uname -r | cut -f 1-2 -d . -)_$(uname -m)_${CC:-cc}_glibc_PTH_64_$([ -n "$BUILD_OPT" ] && echo OPT || echo DBG).OBJ /dist/OBJ-PATH - -ENV LD_LIBRARY_PATH=/dist/OBJ-PATH/lib - -ENV SSLTRACE=100 SSLDEBUG=100 - -# Init test key using an empty noise (seed) file (-z /dev/null). -# Use different subjects, otherwise NSS seems to merge keys under the same nickname. -RUN mkdir /certdb && \ - /dist/OBJ-PATH/bin/certutil -d /certdb -N --empty-password && \ - /dist/OBJ-PATH/bin/certutil -d /certdb -S -n rsa-server -t u -x -s CN=localhost -k rsa -z /dev/null && \ - /dist/OBJ-PATH/bin/certutil -d /certdb -S -n ecdsa-server -t u -x -s CN=localhost,O=EC -k ec -z /dev/null -q nistp256 - -ADD httpreq.txt /httpreq.txt -ADD run.sh /run.sh -ADD server.sh /server.sh -ENTRYPOINT ["/run.sh"] diff --git a/_dev/tstclnt/httpreq.txt b/_dev/tstclnt/httpreq.txt deleted file mode 100644 index e4e6ac1..0000000 --- a/_dev/tstclnt/httpreq.txt +++ /dev/null @@ -1,5 +0,0 @@ -GET / HTTP/1.1 -Host: example.com -Connection: close - - diff --git a/_dev/tstclnt/poll.patch b/_dev/tstclnt/poll.patch deleted file mode 100644 index b7f92bc..0000000 --- a/_dev/tstclnt/poll.patch +++ /dev/null @@ -1,37 +0,0 @@ -diff -r 15c6a01b9fe8 cmd/tstclnt/tstclnt.c ---- a/cmd/tstclnt/tstclnt.c Fri Jun 10 18:34:00 2016 +0100 -+++ b/cmd/tstclnt/tstclnt.c Thu Jun 16 16:26:29 2016 +0100 -@@ -713,7 +713,6 @@ - return NSS_GetClientAuthData(arg, socket, caNames, pRetCert, pRetKey); - } - --#if defined(WIN32) || defined(OS2) - void - thread_main(void *arg) - { -@@ -746,7 +745,6 @@ - PR_Close(ps); - } - --#endif - - static void - printHostNameAndAddr(const char *host, const PRNetAddr *addr) -@@ -1545,7 +1543,8 @@ - npds = 2; - std_out = PR_GetSpecialFD(PR_StandardOutput); - --#if defined(WIN32) || defined(OS2) -+ // Enabled PR_Poll compatibility mode for running in docker run. (sigh). -+ - /* PR_Poll cannot be used with stdin on Windows or OS/2. (sigh). - ** But use of PR_Poll and non-blocking sockets is a major feature - ** of this program. So, we simulate a pollable stdin with a -@@ -1573,7 +1572,6 @@ - goto done; - } - } --#endif - - if (serverCertAuth.testFreshStatusFromSideChannel) { - SSL_ForceHandshake(s); diff --git a/_dev/tstclnt/run.sh b/_dev/tstclnt/run.sh deleted file mode 100755 index 40e3d33..0000000 --- a/_dev/tstclnt/run.sh +++ /dev/null @@ -1,8 +0,0 @@ -#! /bin/bash - -IFS=':' read -ra ADDR <<< "$1" -shift -HOST="${ADDR[0]}" -PORT="${ADDR[1]}" - -exec /dist/OBJ-PATH/bin/tstclnt -D -V tls1.3:tls1.3 -o -O -h $HOST -p $PORT -v -A /httpreq.txt -L 2 -Z "$@" diff --git a/_dev/tstclnt/server.sh b/_dev/tstclnt/server.sh deleted file mode 100755 index 1a1d071..0000000 --- a/_dev/tstclnt/server.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -PATH=/dist/OBJ-PATH/bin:$PATH -set -x - -# RSA -selfserv -n rsa-server -p 1443 -d /certdb -V tls1.2:tls1.3 -v -Z & - -# ECDSA -selfserv -n ecdsa-server -p 2443 -d /certdb -V tls1.2:tls1.3 -v -Z & - -wait diff --git a/_dev/utils/fmtcheck.sh b/_dev/utils/fmtcheck.sh deleted file mode 100755 index 50e45e0..0000000 --- a/_dev/utils/fmtcheck.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh -# Copyright 2012 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -gofiles=$(find . -iname "*.go" ! -path "*/_dev/*") -#[ -z "$gofiles" ] && exit 0 - -unformatted=$(gofmt -l $gofiles) -[ -z "$unformatted" ] && exit 0 - -# Some files are not gofmt'd. Print message and fail. - -echo >&2 "Go files must be formatted with gofmt. Please run:" -for fn in $unformatted; do - echo >&2 " gofmt -w $PWD/$fn" -done - -exit 1 - diff --git a/_dev/utils/pre-commit b/_dev/utils/pre-commit deleted file mode 100755 index 387f555..0000000 --- a/_dev/utils/pre-commit +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh -# Copyright 2012 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -# git gofmt pre-commit hook -# -# To use, store as .git/hooks/pre-commit inside your repository and make sure -# it has execute permissions. -# -# This script does not handle file names that contain spaces. - -gofiles=$(git diff --cached --name-only --diff-filter=ACM | grep '\.go$') -[ -z "$gofiles" ] && exit 0 - -unformatted=$(gofmt -l $gofiles) -[ -z "$unformatted" ] && exit 0 - -# Some files are not gofmt'd. Print message and fail. - -echo >&2 "Go files must be formatted with gofmt. Please run:" -for fn in $unformatted; do - echo >&2 " gofmt -w $PWD/$fn" -done - -exit 1 -