├── VERSION ├── .release-notes ├── next-release.md ├── 1.1.1.md ├── 1.2.4.md ├── 1.1.4.md ├── 1.2.3.md ├── 1.2.1.md ├── 1.1.3.md ├── 1.1.6.md ├── 1.2.2.md ├── 1.1.5.md ├── 1.2.0.md └── 1.1.2.md ├── lock.json ├── .github ├── FUNDING.yml ├── linters │ └── .markdown-lint.yml ├── actionlint.yaml └── workflows │ ├── lint-action-workflows.yml │ ├── release-notes-reminder.yml │ ├── remove-discuss-during-sync.yml │ ├── add-discuss-during-sync.yml │ ├── generate-documentation.yml │ ├── changelog-bot.yml │ ├── release-notes.yml │ ├── announce-a-release.yml │ ├── release.yml │ ├── prepare-for-a-release.yml │ ├── breakage-against-ponyc-latest.yml │ └── pr.yml ├── .markdownlintignore ├── STYLE_GUIDE.md ├── crypto ├── crypto.pony ├── constant_time_compare.pony ├── hash_fn.pony ├── _test.pony └── digest.pony ├── examples ├── digest-example │ └── digest-example.pony └── hash-fn-example │ └── hash-fn-example.pony ├── README.md ├── corral.json ├── RELEASE_PROCESS.md ├── LICENSE ├── Makefile ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md └── make.ps1 /VERSION: -------------------------------------------------------------------------------- 1 | 1.2.4 2 | -------------------------------------------------------------------------------- /.release-notes/next-release.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "locks": [] 3 | } 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | open_collective: ponyc 2 | -------------------------------------------------------------------------------- /.github/linters/.markdown-lint.yml: -------------------------------------------------------------------------------- 1 | { 2 | "MD013": false 3 | } 4 | -------------------------------------------------------------------------------- /.markdownlintignore: -------------------------------------------------------------------------------- 1 | CHANGELOG.md 2 | CODE_OF_CONDUCT.md 3 | .release-notes/ 4 | -------------------------------------------------------------------------------- /.release-notes/1.1.1.md: -------------------------------------------------------------------------------- 1 | ## Internal only release 2 | 3 | This was release was purely for non-public facing changes. 4 | -------------------------------------------------------------------------------- /.github/actionlint.yaml: -------------------------------------------------------------------------------- 1 | # Configuration related to self-hosted runner. 2 | self-hosted-runner: 3 | labels: 4 | - windows-11-arm -------------------------------------------------------------------------------- /.release-notes/1.2.4.md: -------------------------------------------------------------------------------- 1 | ## Enable building on arm64 Windows 2 | 3 | It is now possible to build the `crypto` library on arm64 Windows. 4 | 5 | -------------------------------------------------------------------------------- /STYLE_GUIDE.md: -------------------------------------------------------------------------------- 1 | # Style Guide 2 | 3 | crypto follows the [Pony standard library Style Guide](https://github.com/ponylang/ponyc/blob/main/STYLE_GUIDE.md). 4 | -------------------------------------------------------------------------------- /.release-notes/1.1.4.md: -------------------------------------------------------------------------------- 1 | ## Support Ponyup on Windows 2 | 3 | Added changes to the Windows `make.ps1` script to make sure it still works with ponyup on Windows. 4 | 5 | -------------------------------------------------------------------------------- /.release-notes/1.2.3.md: -------------------------------------------------------------------------------- 1 | ## Update to LibreSSL 3.9.1 on Windows 2 | 3 | The version of LibreSSL used on Windows was updated to 3.9.1 to keep in sync with the `net_ssl` package. 4 | -------------------------------------------------------------------------------- /.release-notes/1.2.1.md: -------------------------------------------------------------------------------- 1 | ## Update to LibreSSL 3.6.1 on Windows 2 | 3 | The version of LibreSSL used on Windows was updated to 3.6.1 to keep in sync with the `net_ssl` package. 4 | 5 | -------------------------------------------------------------------------------- /crypto/crypto.pony: -------------------------------------------------------------------------------- 1 | """ 2 | The crypto package includes a variety of common cryptographic algorithms 3 | and functions often useful in cryptographic code for their use in information 4 | security. 5 | """ 6 | 7 | use @pony_ctx[Pointer[None]]() 8 | use @pony_alloc[Pointer[U8]](ctx: Pointer[None], size: USize) 9 | -------------------------------------------------------------------------------- /.release-notes/1.1.3.md: -------------------------------------------------------------------------------- 1 | ## Forward prepare for coming breaking FFI change in ponyc 2 | 3 | Added FFI declarations to all FFI calls in the library. The change has no impact on end users, but will future proof against a coming breaking change in FFI in the ponyc compiler. Users of this version of the library won't be impacted by the coming change. 4 | 5 | -------------------------------------------------------------------------------- /.release-notes/1.1.6.md: -------------------------------------------------------------------------------- 1 | ## Add path to Homebrew's LibreSSL on ARM macOS 2 | 3 | With the release of ponyc 0.45.0, Apple Silicon is now a supported platform, which means that the default install location of Homebrew formulas has changed. This release of crypto allows one to build the library without using the ponyc `--path` option to include LibreSSL. 4 | 5 | -------------------------------------------------------------------------------- /examples/digest-example/digest-example.pony: -------------------------------------------------------------------------------- 1 | // in your code this `use` statement would be: 2 | // use "crypto" 3 | use "../../crypto" 4 | 5 | actor Main 6 | new create(env: Env) => 7 | let sha256digest: Digest = Digest.sha256() 8 | try 9 | sha256digest.append("Hello ")? 10 | sha256digest.append("World")? 11 | let hash: Array[U8] val = sha256digest.final() 12 | env.out.print("SHA256: " + ToHexString(hash)) 13 | else 14 | env.out.print("Error computing hash") 15 | end 16 | -------------------------------------------------------------------------------- /.release-notes/1.2.2.md: -------------------------------------------------------------------------------- 1 | ## Update the URL for Windows LibreSSL downloads 2 | 3 | Previously, as part of the Windows install process of `crypto`, we would download a copy of LibreSSL from ftp.openbsd.org, build and install it. 4 | 5 | We've found that ftp.openbsd.org has become flakey but cdn.openbsd.org has been stable. 6 | 7 | There's no change that you need to do as a user for this update, however, if you are having trouble with this library on Windows due to it being unable to successfully download LibreSSL, this update is for you. 8 | 9 | -------------------------------------------------------------------------------- /examples/hash-fn-example/hash-fn-example.pony: -------------------------------------------------------------------------------- 1 | // in your code this `use` statement would be: 2 | // use "crypto" 3 | use "../../crypto" 4 | 5 | actor Main 6 | new create(env: Env) => 7 | let md5hash: Array[U8] val = MD5("Hello World") 8 | env.out.print("MD5: " + ToHexString(md5hash)) 9 | 10 | let sha1hash: Array[U8] val = SHA1("Hello World") 11 | env.out.print("SHA1: " + ToHexString(sha1hash)) 12 | 13 | let sha256hash: Array[U8] val = SHA256("Hello World") 14 | env.out.print("SHA256: " + ToHexString(sha256hash)) 15 | -------------------------------------------------------------------------------- /.release-notes/1.1.5.md: -------------------------------------------------------------------------------- 1 | ## Update to work with ponytest name change in Pony 0.49.0 2 | 3 | The Pony unit testing framework PonyTest had [its package name renamed](https://github.com/ponylang/ponyc/pull/4032) from `ponytest` to `pony_test` to match standard library naming conventions. We've updated to account for the new name. 4 | 5 | ## Updates for libs build on Windows 6 | 7 | We removed a hard-coded Visual Studio version from the build script so that it can be built with more versions of Visual Studio. 8 | We upgraded the LibreSSL version to 3.5.0. 9 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # crypto 2 | 3 | Library of common cryptographic algorithms and functions for Pony. Requires LibreSSL or OpenSSL. See installation for more details. 4 | 5 | ## Status 6 | 7 | Deprecated. Use [ponylang/ssl](https://github.com/ponylang/ssl) instead. 8 | 9 | To update from `crypto` to `ssl`, should update your dependency in corral.json to the most recent ponylang/ssl version. As of version 1.0.0, the API is compatible with `crypto` but there is a small breaking change. Where you previously had `use "crypto"` you will now need to do `use "ssl/crypto"`. 10 | -------------------------------------------------------------------------------- /corral.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "crypto" 4 | ], 5 | "deps": [], 6 | "info": { 7 | "description": "Library of common cryptographic algorithms and functions", 8 | "homepage": "https://github.com/ponylang/crypto", 9 | "license": "BSD-2-Clause", 10 | "documentation_url": "https://ponylang.github.io/crypto/", 11 | "version": "1.2.4", 12 | "name": "crypto" 13 | }, 14 | "scripts": { 15 | "windows": { 16 | "post_fetch_or_update": "PowerShell.exe -File make.ps1 -Config release -Command libs" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.github/workflows/lint-action-workflows.yml: -------------------------------------------------------------------------------- 1 | name: Lint GitHub Action Workflows 2 | 3 | on: pull_request 4 | 5 | concurrency: 6 | group: lint-actions-${{ github.ref }} 7 | cancel-in-progress: true 8 | 9 | permissions: 10 | packages: read 11 | 12 | jobs: 13 | lint: 14 | name: Lint 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v4.1.1 19 | - name: Check workflow files 20 | uses: docker://ghcr.io/ponylang/shared-docker-ci-actionlint:20250119 21 | with: 22 | args: -color 23 | -------------------------------------------------------------------------------- /.github/workflows/release-notes-reminder.yml: -------------------------------------------------------------------------------- 1 | name: Release Notes Reminder 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - labeled 7 | 8 | permissions: 9 | packages: read 10 | pull-requests: write 11 | 12 | jobs: 13 | release-note-reminder: 14 | runs-on: ubuntu-latest 15 | name: Prompt to add release notes 16 | steps: 17 | - name: Prompt to add release notes 18 | uses: docker://ghcr.io/ponylang/release-notes-reminder-bot-action:0.1.1 19 | env: 20 | API_CREDENTIALS: ${{ secrets.PONYLANG_MAIN_API_TOKEN }} 21 | 22 | -------------------------------------------------------------------------------- /.github/workflows/remove-discuss-during-sync.yml: -------------------------------------------------------------------------------- 1 | name: Remove discuss during sync label 2 | 3 | on: 4 | issues: 5 | types: 6 | - closed 7 | pull_request_target: 8 | types: 9 | - closed 10 | 11 | permissions: 12 | pull-requests: write 13 | 14 | jobs: 15 | remove-label: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Remove label 19 | uses: andymckay/labeler@467347716a3bdbca7f277cb6cd5fa9c5205c5412 20 | with: 21 | repo-token: ${{ secrets.PONYLANG_MAIN_API_TOKEN }} 22 | remove-labels: "discuss during sync" 23 | -------------------------------------------------------------------------------- /crypto/constant_time_compare.pony: -------------------------------------------------------------------------------- 1 | primitive ConstantTimeCompare 2 | fun apply[S: ByteSeq box = ByteSeq box](xs: S, ys: S): Bool => 3 | """ 4 | Return true if the two ByteSeqs, xs and ys, have equal contents. The time 5 | taken is independent of the contents. 6 | """ 7 | if xs.size() != ys.size() then 8 | false 9 | else 10 | var v = U8(0) 11 | var i: USize = 0 12 | while i < xs.size() do 13 | try 14 | v = v or (xs(i)? xor ys(i)?) 15 | else 16 | return false 17 | end 18 | i = i + 1 19 | end 20 | v == 0 21 | end 22 | -------------------------------------------------------------------------------- /.release-notes/1.2.0.md: -------------------------------------------------------------------------------- 1 | ## Remove `md4` constructor from `Digest` 2 | 3 | With the introduction of OpenSSL 3, the OpenSSL developers have moved MD4 to a "legacy provider". What this means is that via the mechanism that the `Digest` class uses, we can no longer cleanly support MD4 without adding bloat that would impact on the usability of the other algorithms supported by `Digest`. 4 | 5 | The `md4` constructor has been removed from `Digest`. Note that an alternate method of doing `md4` hashing is still available via the `MD4` primitive. 6 | 7 | ## Add OpenSSL 3 support 8 | 9 | We've added support for using SSL libraries that support the OpenSSL 3 API. 10 | 11 | -------------------------------------------------------------------------------- /.release-notes/1.1.2.md: -------------------------------------------------------------------------------- 1 | ## Free the underlying digest context on OpenSSL 0.9.0 2 | 3 | The code under OpenSSL 0.9.0 was using EVP_MD_CTX_cleanup, which doesn't free the underlying context. This means that the memory allocated with EVP_MD_CTX_create would never be freed, leading to a potential memory leak. This is now fixed by using the appropriate function, EVP_MD_CTX_destroy. 4 | 5 | ## Forward prepare for coming breaking FFI change in ponyc 6 | 7 | Added FFI declarations to all FFI calls in the library. The change has no impact on end users, but will future proof against a coming breaking change in FFI in the ponyc compiler. Users of this version of the library won't be impacted by the coming change. 8 | 9 | -------------------------------------------------------------------------------- /.github/workflows/add-discuss-during-sync.yml: -------------------------------------------------------------------------------- 1 | name: Add discuss during sync label 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | - reopened 8 | issue_comment: 9 | types: 10 | - created 11 | pull_request_target: 12 | types: 13 | - opened 14 | - edited 15 | - ready_for_review 16 | - reopened 17 | pull_request_review: 18 | types: 19 | - submitted 20 | 21 | permissions: 22 | pull-requests: write 23 | 24 | jobs: 25 | add-label: 26 | runs-on: ubuntu-latest 27 | steps: 28 | - name: Add "discuss during sync" label to active GH entity 29 | uses: andymckay/labeler@467347716a3bdbca7f277cb6cd5fa9c5205c5412 30 | with: 31 | repo-token: ${{ secrets.PONYLANG_MAIN_API_TOKEN }} 32 | add-labels: "discuss during sync" 33 | -------------------------------------------------------------------------------- /RELEASE_PROCESS.md: -------------------------------------------------------------------------------- 1 | # How to cut a crypto release 2 | 3 | This document is aimed at members of the Pony team who might be cutting a release of Pony. It serves as a checklist that can take you through doing a release step-by-step. 4 | 5 | ## Prerequisites 6 | 7 | You must have commit access to the crypto repository 8 | 9 | ## Releasing 10 | 11 | Please note that this document was written with the assumption that you are using a clone of the `crypto` repo. You have to be using a clone rather than a fork. It is advised to your do this by making a fresh clone of the `crypto` repo from which you will release. 12 | 13 | ```bash 14 | git clone git@github.com:ponylang/crypto.git crypto-release-clean 15 | cd crypto-release-clean 16 | ``` 17 | 18 | Before getting started, you will need a number for the version that you will be releasing as well as an agreed upon "golden commit" that will form the basis of the release. 19 | 20 | The "golden commit" must be `HEAD` on the `main` branch of this repository. At this time, releasing from any other location is not supported. 21 | 22 | For the duration of this document, that we are releasing version is `0.3.1`. Any place you see those values, please substitute your own version. 23 | 24 | ```bash 25 | git tag release-0.3.1 26 | git push origin release-0.3.1 27 | ``` 28 | -------------------------------------------------------------------------------- /.github/workflows/generate-documentation.yml: -------------------------------------------------------------------------------- 1 | name: Manually generate documentation 2 | 3 | on: 4 | workflow_dispatch 5 | 6 | permissions: 7 | contents: read 8 | pages: write 9 | id-token: write 10 | packages: read 11 | 12 | concurrency: 13 | group: "update-documentation" 14 | cancel-in-progress: true 15 | 16 | jobs: 17 | generate-documentation: 18 | name: Generate documentation for release 19 | environment: 20 | name: github-pages 21 | url: ${{ steps.deployment.outputs.page_url }} 22 | runs-on: ubuntu-latest 23 | container: 24 | image: ghcr.io/ponylang/library-documentation-action-v2-insiders:release 25 | steps: 26 | - name: Checkout 27 | uses: actions/checkout@v4.1.1 28 | - name: Generate documentation 29 | run: /entrypoint.py 30 | env: 31 | INPUT_SITE_URL: "https://ponylang.github.io/crypto/" 32 | INPUT_LIBRARY_NAME: "crypto" 33 | INPUT_DOCS_BUILD_DIR: "build/crypto-docs" 34 | - name: Setup Pages 35 | uses: actions/configure-pages@v5 36 | - name: Upload artifact 37 | uses: actions/upload-pages-artifact@v3 38 | with: 39 | path: 'build/crypto-docs/site/' 40 | - name: Deploy to GitHub Pages 41 | id: deployment 42 | uses: actions/deploy-pages@v4 43 | -------------------------------------------------------------------------------- /.github/workflows/changelog-bot.yml: -------------------------------------------------------------------------------- 1 | name: Changelog Bot 2 | 3 | on: 4 | push: 5 | branches: 6 | - '**' 7 | tags-ignore: 8 | - '**' 9 | paths-ignore: 10 | - CHANGELOG.md 11 | 12 | permissions: 13 | packages: read 14 | pull-requests: read 15 | contents: write 16 | 17 | jobs: 18 | changelog-bot: 19 | runs-on: ubuntu-latest 20 | name: Update CHANGELOG.md 21 | steps: 22 | - name: Update Changelog 23 | uses: docker://ghcr.io/ponylang/changelog-bot-action:0.3.7 24 | with: 25 | GIT_USER_NAME: "Ponylang Main Bot" 26 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | - name: Send alert on failure 30 | if: ${{ failure() }} 31 | uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 32 | with: 33 | api-key: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_API_KEY }} 34 | email: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_EMAIL }} 35 | organization-url: 'https://ponylang.zulipchat.com/' 36 | to: notifications 37 | type: stream 38 | topic: ${{ github.repository }} unattended job failure 39 | content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed. 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2016-2018, The Pony Developers 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /.github/workflows/release-notes.yml: -------------------------------------------------------------------------------- 1 | name: Release Notes 2 | 3 | on: 4 | push: 5 | branches: 6 | - '**' 7 | tags-ignore: 8 | - '**' 9 | paths-ignore: 10 | - .release-notes/next-release.md 11 | - .release-notes/\d+.\d+.\d+.md 12 | 13 | permissions: 14 | packages: read 15 | pull-requests: read 16 | contents: write 17 | 18 | jobs: 19 | release-notes: 20 | runs-on: ubuntu-latest 21 | name: Update release notes 22 | steps: 23 | - name: Update 24 | uses: docker://ghcr.io/ponylang/release-notes-bot-action:0.3.10 25 | with: 26 | GIT_USER_NAME: "Ponylang Main Bot" 27 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 28 | env: 29 | API_CREDENTIALS: ${{ secrets.GITHUB_TOKEN }} 30 | - name: Send alert on failure 31 | if: ${{ failure() }} 32 | uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 33 | with: 34 | api-key: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_API_KEY }} 35 | email: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_EMAIL }} 36 | organization-url: 'https://ponylang.zulipchat.com/' 37 | to: notifications 38 | type: stream 39 | topic: ${{ github.repository }} scheduled job failure 40 | content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed. 41 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | config ?= release 2 | 3 | PACKAGE := crypto 4 | GET_DEPENDENCIES_WITH := corral fetch 5 | CLEAN_DEPENDENCIES_WITH := corral clean 6 | COMPILE_WITH := corral run -- ponyc 7 | 8 | BUILD_DIR ?= build/$(config) 9 | SRC_DIR ?= $(PACKAGE) 10 | EXAMPLES_DIR := examples 11 | tests_binary := $(BUILD_DIR)/$(PACKAGE) 12 | docs_dir := build/$(PACKAGE)-docs 13 | 14 | ifdef config 15 | ifeq (,$(filter $(config),debug release)) 16 | $(error Unknown configuration "$(config)") 17 | endif 18 | endif 19 | 20 | ifeq ($(config),release) 21 | PONYC = $(COMPILE_WITH) 22 | else 23 | PONYC = $(COMPILE_WITH) --debug 24 | endif 25 | 26 | ifeq (,$(filter $(MAKECMDGOALS),clean docs realclean TAGS)) 27 | ifeq ($(ssl), 3.0.x) 28 | SSL = -Dopenssl_3.0.x 29 | else ifeq ($(ssl), 1.1.x) 30 | SSL = -Dopenssl_1.1.x 31 | else ifeq ($(ssl), 0.9.0) 32 | SSL = -Dopenssl_0.9.0 33 | else 34 | $(error Unknown SSL version "$(ssl)". Must set using 'ssl=1.1.x' or 'ssl=0.9.0') 35 | endif 36 | endif 37 | 38 | SOURCE_FILES := $(shell find $(SRC_DIR) -name *.pony) 39 | EXAMPLES := $(notdir $(shell find $(EXAMPLES_DIR)/* -type d)) 40 | EXAMPLES_SOURCE_FILES := $(shell find $(EXAMPLES_DIR) -name *.pony) 41 | EXAMPLES_BINARIES := $(addprefix $(BUILD_DIR)/,$(EXAMPLES)) 42 | 43 | test: unit-tests build-examples 44 | 45 | unit-tests: $(tests_binary) 46 | $^ --exclude=integration --sequential 47 | 48 | $(tests_binary): $(GEN_FILES) $(SOURCE_FILES) | $(BUILD_DIR) 49 | $(GET_DEPENDENCIES_WITH) 50 | $(PONYC) $(SSL) -o $(BUILD_DIR) $(SRC_DIR) 51 | 52 | build-examples: $(EXAMPLES_BINARIES) 53 | 54 | $(EXAMPLES_BINARIES): $(BUILD_DIR)/%: $(SOURCE_FILES) $(EXAMPLES_SOURCE_FILES) | $(BUILD_DIR) 55 | $(GET_DEPENDENCIES_WITH) 56 | $(PONYC) $(SSL) -o $(BUILD_DIR) $(EXAMPLES_DIR)/$* 57 | 58 | clean: 59 | $(CLEAN_DEPENDENCIES_WITH) 60 | rm -rf $(BUILD_DIR) 61 | 62 | $(docs_dir): $(GEN_FILES) $(SOURCE_FILES) 63 | rm -rf $(docs_dir) 64 | $(PONYC) --docs-public --pass=docs --output build $(SRC_DIR) 65 | 66 | docs: $(docs_dir) 67 | 68 | TAGS: 69 | ctags --recurse=yes $(SRC_DIR) 70 | 71 | all: test 72 | 73 | $(BUILD_DIR): 74 | mkdir -p $(BUILD_DIR) 75 | 76 | .PHONY: all build-examples clean TAGS test 77 | -------------------------------------------------------------------------------- /.github/workflows/announce-a-release.yml: -------------------------------------------------------------------------------- 1 | name: Announce a release 2 | 3 | on: 4 | push: 5 | tags: 'announce-[0-9]+.[0-9]+.[0-9]+' 6 | 7 | concurrency: announce-a-release 8 | 9 | permissions: 10 | packages: read 11 | contents: write 12 | 13 | jobs: 14 | announce: 15 | name: Announcements 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout main 19 | uses: actions/checkout@v4.1.1 20 | with: 21 | ref: "main" 22 | token: ${{ secrets.RELEASE_TOKEN }} 23 | - name: Release notes 24 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 25 | with: 26 | entrypoint: publish-release-notes-to-github 27 | env: 28 | RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} 29 | - name: Zulip 30 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 31 | with: 32 | entrypoint: send-announcement-to-pony-zulip 33 | env: 34 | ZULIP_API_KEY: ${{ secrets.ZULIP_RELEASE_API_KEY }} 35 | ZULIP_EMAIL: ${{ secrets.ZULIP_RELEASE_EMAIL }} 36 | - name: Last Week in Pony 37 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 38 | with: 39 | entrypoint: add-announcement-to-last-week-in-pony 40 | env: 41 | RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} 42 | 43 | post-announcement: 44 | name: Tasks to run after the release has been announced 45 | needs: 46 | - announce 47 | runs-on: ubuntu-latest 48 | steps: 49 | - name: Checkout main 50 | uses: actions/checkout@v4.1.1 51 | with: 52 | ref: "main" 53 | token: ${{ secrets.RELEASE_TOKEN }} 54 | - name: Rotate release notes 55 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 56 | with: 57 | entrypoint: rotate-release-notes 58 | env: 59 | GIT_USER_NAME: "Ponylang Main Bot" 60 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 61 | - name: Delete announcement trigger tag 62 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 63 | with: 64 | entrypoint: delete-announcement-tag 65 | env: 66 | GIT_USER_NAME: "Ponylang Main Bot" 67 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 68 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - '[0-9]+.[0-9]+.[0-9]+' 7 | 8 | concurrency: release 9 | 10 | permissions: 11 | contents: read 12 | pages: write 13 | id-token: write 14 | packages: read 15 | 16 | jobs: 17 | # validation to assure that we should in fact continue with the release should 18 | # be done here. the primary reason for this step is to verify that the release 19 | # was started correctly by pushing a `release-X.Y.Z` tag rather than `X.Y.Z`. 20 | pre-artefact-creation: 21 | name: Tasks to run before artefact creation 22 | runs-on: ubuntu-latest 23 | steps: 24 | - name: Checkout main 25 | uses: actions/checkout@v4.1.1 26 | with: 27 | ref: "main" 28 | token: ${{ secrets.RELEASE_TOKEN }} 29 | - name: Validate CHANGELOG 30 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 31 | with: 32 | entrypoint: pre-artefact-changelog-check 33 | 34 | generate-documentation: 35 | name: Generate documentation for release 36 | environment: 37 | name: github-pages 38 | url: ${{ steps.deployment.outputs.page_url }} 39 | runs-on: ubuntu-latest 40 | needs: 41 | - pre-artefact-creation 42 | container: 43 | image: ghcr.io/ponylang/library-documentation-action-v2-insiders:release 44 | steps: 45 | - name: Checkout 46 | uses: actions/checkout@v4.1.1 47 | with: 48 | ref: "main" 49 | token: ${{ secrets.RELEASE_TOKEN }} 50 | - name: Generate documentation 51 | run: /entrypoint.py 52 | env: 53 | INPUT_SITE_URL: "https://ponylang.github.io/crypto/" 54 | INPUT_LIBRARY_NAME: "crypto" 55 | INPUT_DOCS_BUILD_DIR: "build/crypto-docs" 56 | - name: Setup Pages 57 | uses: actions/configure-pages@v5 58 | - name: Upload artifact 59 | uses: actions/upload-pages-artifact@v3 60 | with: 61 | path: 'build/crypto-docs/site/' 62 | - name: Deploy to GitHub Pages 63 | id: deployment 64 | uses: actions/deploy-pages@v4 65 | 66 | trigger-release-announcement: 67 | name: Trigger release announcement 68 | runs-on: ubuntu-latest 69 | needs: 70 | - generate-documentation 71 | steps: 72 | - uses: actions/checkout@v4.1.1 73 | with: 74 | ref: "main" 75 | token: ${{ secrets.RELEASE_TOKEN }} 76 | - name: Trigger 77 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 78 | with: 79 | entrypoint: trigger-release-announcement 80 | env: 81 | GIT_USER_NAME: "Ponylang Main Bot" 82 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 83 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this library will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/) and [Keep a CHANGELOG](http://keepachangelog.com/). 4 | 5 | ## [unreleased] - unreleased 6 | 7 | ### Fixed 8 | 9 | 10 | ### Added 11 | 12 | 13 | ### Changed 14 | 15 | 16 | ## [1.2.4] - 2025-06-03 17 | 18 | ### Added 19 | 20 | - Enable building on arm64 Windows ([PR #111](https://github.com/ponylang/crypto/pull/111)) 21 | 22 | ## [1.2.3] - 2024-04-20 23 | 24 | ### Changed 25 | 26 | - - Update to LibreSSL 3.9.1 on Windows ([PR #106](https://github.com/ponylang/crypto/pull/106)) 27 | 28 | ## [1.2.2] - 2023-04-27 29 | 30 | ### Changed 31 | 32 | - Change location we download LibreSSL from for Windows Users ([PR #85](https://github.com/ponylang/crypto/pull/85)) 33 | 34 | ## [1.2.1] - 2023-01-05 35 | 36 | ### Changed 37 | 38 | - Update to LibreSSL 3.6.1 on Windows ([PR #81](https://github.com/ponylang/crypto/pull/81)) 39 | 40 | ## [1.2.0] - 2023-01-03 41 | 42 | ### Added 43 | 44 | - Add OpenSSL 3 support ([PR #80](https://github.com/ponylang/crypto/pull/80)) 45 | 46 | ### Changed 47 | 48 | - Remove `md4` constructor from `Digest` ([PR #78](https://github.com/ponylang/crypto/pull/78)) 49 | 50 | ## [1.1.6] - 2022-05-27 51 | 52 | ### Added 53 | 54 | - Add path to Homebrew's LibreSSL on ARM macOS ([PR #73](https://github.com/ponylang/crypto/pull/73)) 55 | 56 | ## [1.1.5] - 2022-02-26 57 | 58 | ### Fixed 59 | 60 | - Update to address PonyTest package being renamed ([PR #67](https://github.com/ponylang/crypto/pull/67)) 61 | - Updates for libs build on Windows ([PR #68](https://github.com/ponylang/crypto/pull/68)) 62 | 63 | ## [1.1.4] - 2022-02-10 64 | 65 | ### Added 66 | 67 | - Support for using ponyup on Windows ([PR #66](https://github.com/ponylang/crypto/pull/66)) 68 | 69 | ## [1.1.3] - 2021-04-10 70 | 71 | ### Changed 72 | 73 | - Remove explicit return type from FFI calls ([PR #57](https://github.com/ponylang/crypto/pull/57)) 74 | 75 | ## [1.1.2] - 2021-03-26 76 | 77 | ### Fixed 78 | 79 | - Free the underlying digest context on OpenSSL 0.9.0 ([PR #55](https://github.com/ponylang/crypto/pull/55)) 80 | 81 | ### Changed 82 | 83 | - Declare all FFI functions ([PR #56](https://github.com/ponylang/crypto/pull/56)) 84 | 85 | ## [1.1.1] - 2021-02-08 86 | 87 | ## [1.1.0] - 2020-08-22 88 | 89 | ### Added 90 | 91 | - Build Windows libs upon fetch or update ([PR #45](https://github.com/ponylang/crypto/pull/45)) 92 | 93 | ## [1.0.2] - 2020-08-13 94 | 95 | ### Added 96 | 97 | - Added Shake128/256 Digest support ([PR #28](https://github.com/ponylang/crypto/pull/28)) 98 | - Added MD4 digest ([PR #27](https://github.com/ponylang/crypto/pull/27)) 99 | - Made Windows installation easier (https://github.com/ponylang/crypto/commit/bed88fa975ec23153e926551c020c2241763f114) 100 | 101 | ## [1.0.1] - 2020-05-17 102 | 103 | ### Fixed 104 | 105 | - Improve performance of constant time comparison ([PR #24](https://github.com/ponylang/crypto/pull/24)) 106 | 107 | ## [1.0.0] - 2019-09-02 108 | 109 | ### Added 110 | 111 | - Initial version 112 | 113 | -------------------------------------------------------------------------------- /.github/workflows/prepare-for-a-release.yml: -------------------------------------------------------------------------------- 1 | name: Prepare for a release 2 | 3 | on: 4 | push: 5 | tags: 'release-[0-9]+.[0-9]+.[0-9]+' 6 | 7 | concurrency: prepare-for-a-release 8 | 9 | permissions: 10 | packages: read 11 | contents: write 12 | 13 | jobs: 14 | # all tasks that need to be done before we add an X.Y.Z tag 15 | # should be done as a step in the pre-tagging job. 16 | # think of it like this... if when you later checkout the tag for a release, 17 | # should the change be there? if yes, do it here. 18 | pre-tagging: 19 | name: Tasks run before tagging the release 20 | runs-on: ubuntu-latest 21 | steps: 22 | - name: Checkout main 23 | uses: actions/checkout@v4.1.1 24 | with: 25 | ref: "main" 26 | token: ${{ secrets.RELEASE_TOKEN }} 27 | - name: Update CHANGELOG.md 28 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 29 | with: 30 | entrypoint: update-changelog-for-release 31 | env: 32 | GIT_USER_NAME: "Ponylang Main Bot" 33 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 34 | - name: Update VERSION 35 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 36 | with: 37 | entrypoint: update-version-in-VERSION 38 | env: 39 | GIT_USER_NAME: "Ponylang Main Bot" 40 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 41 | - name: Update version in README 42 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 43 | with: 44 | entrypoint: update-version-in-README 45 | env: 46 | GIT_USER_NAME: "Ponylang Main Bot" 47 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 48 | - name: Update corral.json 49 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 50 | with: 51 | entrypoint: update-version-in-corral-json 52 | env: 53 | GIT_USER_NAME: "Ponylang Main Bot" 54 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 55 | 56 | # tag for release 57 | # this will kick off the next stage of the release process 58 | # no additional steps should be added to this job 59 | tag-release: 60 | name: Tag the release 61 | needs: 62 | - pre-tagging 63 | runs-on: ubuntu-latest 64 | steps: 65 | - name: Checkout main 66 | uses: actions/checkout@v4.1.1 67 | with: 68 | ref: "main" 69 | token: ${{ secrets.RELEASE_TOKEN }} 70 | - name: Trigger artefact creation 71 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 72 | with: 73 | entrypoint: trigger-artefact-creation 74 | env: 75 | GIT_USER_NAME: "Ponylang Main Bot" 76 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 77 | 78 | # all cleanup tags that should happen after tagging for release should happen 79 | # in the post-tagging job. examples of things you might do: 80 | # add a new unreleased section to a changelog 81 | # set a version back to "snapshot" 82 | # in general, post-tagging is for "going back to normal" from tasks that were 83 | # done during the pre-tagging job 84 | post-tagging: 85 | name: Tasks run after tagging the release 86 | needs: 87 | - tag-release 88 | runs-on: ubuntu-latest 89 | steps: 90 | - name: Checkout main 91 | uses: actions/checkout@v4.1.1 92 | with: 93 | ref: "main" 94 | token: ${{ secrets.RELEASE_TOKEN }} 95 | - name: Add "unreleased" section to CHANGELOG.md 96 | uses: docker://ghcr.io/ponylang/release-bot-action:0.6.3 97 | with: 98 | entrypoint: add-unreleased-section-to-changelog 99 | env: 100 | GIT_USER_NAME: "Ponylang Main Bot" 101 | GIT_USER_EMAIL: "ponylang.main@gmail.com" 102 | -------------------------------------------------------------------------------- /.github/workflows/breakage-against-ponyc-latest.yml: -------------------------------------------------------------------------------- 1 | name: ponyc update breakage test 2 | 3 | on: 4 | repository_dispatch: 5 | types: [shared-docker-linux-builders-updated] 6 | 7 | permissions: 8 | packages: read 9 | 10 | jobs: 11 | test-libressl-3-vs-ponyc-latest: 12 | name: libressl 3.x with ponyc main 13 | runs-on: ubuntu-latest 14 | container: 15 | image: ghcr.io/ponylang/shared-docker-ci-x86-64-unknown-linux-builder-with-libressl-3.9.2:latest 16 | steps: 17 | - uses: actions/checkout@v4.1.1 18 | - name: Test 19 | run: make test config=debug ssl=0.9.0 20 | - name: Send alert on failure 21 | if: ${{ failure() }} 22 | uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 23 | with: 24 | api-key: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_API_KEY }} 25 | email: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_EMAIL }} 26 | organization-url: 'https://ponylang.zulipchat.com/' 27 | to: notifications 28 | type: stream 29 | topic: ${{ github.repository }} scheduled job failure 30 | content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed. 31 | 32 | test-libressl-4-vs-ponyc-latest: 33 | name: libressl 4.x with ponyc main 34 | runs-on: ubuntu-latest 35 | container: 36 | image: ghcr.io/ponylang/shared-docker-ci-x86-64-unknown-linux-builder-with-libressl-4.0.0:latest 37 | steps: 38 | - uses: actions/checkout@v4.1.1 39 | - name: Test 40 | run: make test config=debug ssl=0.9.0 41 | - name: Send alert on failure 42 | if: ${{ failure() }} 43 | uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 44 | with: 45 | api-key: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_API_KEY }} 46 | email: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_EMAIL }} 47 | organization-url: 'https://ponylang.zulipchat.com/' 48 | to: notifications 49 | type: stream 50 | topic: ${{ github.repository }} scheduled job failure 51 | content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed. 52 | 53 | test-openssl-1-vs-ponyc-latest: 54 | name: openssl 1.x with ponyc main 55 | runs-on: ubuntu-latest 56 | container: 57 | image: ghcr.io/ponylang/shared-docker-ci-x86-64-unknown-linux-builder-with-openssl_1.1.1w:latest 58 | steps: 59 | - uses: actions/checkout@v4.1.1 60 | - name: Test 61 | run: make test config=debug ssl=1.1.x 62 | - name: Send alert on failure 63 | if: ${{ failure() }} 64 | uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 65 | with: 66 | api-key: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_API_KEY }} 67 | email: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_EMAIL }} 68 | organization-url: 'https://ponylang.zulipchat.com/' 69 | to: notifications 70 | type: stream 71 | topic: ${{ github.repository }} scheduled job failure 72 | content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed. 73 | 74 | test-openssl-3-vs-ponyc-latest: 75 | name: openssl 3.x with ponyc main 76 | runs-on: ubuntu-latest 77 | container: 78 | image: ghcr.io/ponylang/shared-docker-ci-x86-64-unknown-linux-builder-with-openssl_3.1.3:latest 79 | steps: 80 | - uses: actions/checkout@v4.1.1 81 | - name: Test 82 | run: make test config=debug ssl=3.0.x 83 | - name: Send alert on failure 84 | if: ${{ failure() }} 85 | uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 86 | with: 87 | api-key: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_API_KEY }} 88 | email: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_EMAIL }} 89 | organization-url: 'https://ponylang.zulipchat.com/' 90 | to: notifications 91 | type: stream 92 | topic: ${{ github.repository }} scheduled job failure 93 | content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed. 94 | -------------------------------------------------------------------------------- /.github/workflows/pr.yml: -------------------------------------------------------------------------------- 1 | name: PR 2 | 3 | on: pull_request 4 | 5 | concurrency: 6 | group: pr-${{ github.ref }} 7 | cancel-in-progress: true 8 | 9 | permissions: 10 | packages: read 11 | 12 | jobs: 13 | superlinter: 14 | name: Lint bash, docker, markdown, and yaml 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4.1.1 18 | - name: Lint codebase 19 | uses: docker://github/super-linter:v3.8.3 20 | env: 21 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 22 | VALIDATE_ALL_CODEBASE: true 23 | VALIDATE_BASH: true 24 | VALIDATE_DOCKERFILE: true 25 | VALIDATE_MD: true 26 | VALIDATE_YAML: true 27 | 28 | verify-changelog: 29 | name: Verify CHANGELOG is valid 30 | runs-on: ubuntu-latest 31 | steps: 32 | - uses: actions/checkout@v4.1.1 33 | - name: Verify CHANGELOG 34 | uses: docker://ghcr.io/ponylang/changelog-tool:release 35 | with: 36 | args: changelog-tool verify 37 | 38 | test-libressl-3-vs-ponyc-release: 39 | name: libressl 3.x with most recent ponyc release 40 | runs-on: ubuntu-latest 41 | container: 42 | image: ghcr.io/ponylang/shared-docker-ci-x86-64-unknown-linux-builder-with-libressl-3.9.2:release 43 | steps: 44 | - uses: actions/checkout@v4.1.1 45 | - name: Test 46 | run: make test config=debug ssl=0.9.0 47 | 48 | test-libressl-4-vs-ponyc-release: 49 | name: libressl 4.x with most recent ponyc release 50 | runs-on: ubuntu-latest 51 | container: 52 | image: ghcr.io/ponylang/shared-docker-ci-x86-64-unknown-linux-builder-with-libressl-4.0.0:release 53 | steps: 54 | - uses: actions/checkout@v4.1.1 55 | - name: Test 56 | run: make test config=debug ssl=0.9.0 57 | 58 | test-openssl-1-vs-ponyc-release: 59 | name: openssl 1.x with most recent ponyc release 60 | runs-on: ubuntu-latest 61 | container: 62 | image: ghcr.io/ponylang/shared-docker-ci-x86-64-unknown-linux-builder-with-openssl_1.1.1w:release 63 | steps: 64 | - uses: actions/checkout@v4.1.1 65 | - name: Test 66 | run: make test config=debug ssl=1.1.x 67 | 68 | test-openssl-3-vs-ponyc-release: 69 | name: openssl 3.x with most recent ponyc release 70 | runs-on: ubuntu-latest 71 | container: 72 | image: ghcr.io/ponylang/shared-docker-ci-x86-64-unknown-linux-builder-with-openssl_3.3.2:release 73 | steps: 74 | - uses: actions/checkout@v4.1.1 75 | - name: Test 76 | run: make test config=debug ssl=3.0.x 77 | 78 | test-x86-64-windows-vs-ponyc-release: 79 | name: Windows x86-64 (LibreSSL) with most recent ponyc release 80 | runs-on: windows-2025 81 | steps: 82 | - uses: actions/checkout@v4.1.1 83 | - name: Test with most recent ponyc release 84 | run: | 85 | Invoke-WebRequest https://dl.cloudsmith.io/public/ponylang/releases/raw/versions/latest/ponyc-x86-64-pc-windows-msvc.zip -OutFile C:\ponyc.zip; 86 | Expand-Archive -Force -Path C:\ponyc.zip -DestinationPath C:\ponyc; 87 | Invoke-WebRequest https://dl.cloudsmith.io/public/ponylang/releases/raw/versions/latest/corral-x86-64-pc-windows-msvc.zip -OutFile C:\corral.zip; 88 | Expand-Archive -Force -Path C:\corral.zip -DestinationPath C:\ponyc; 89 | $env:PATH = 'C:\ponyc\bin;' + $env:PATH; 90 | .\make.ps1 -Command libs 2>&1; 91 | .\make.ps1 -Command test 2>&1; 92 | 93 | test-arm64-windows-vs-ponyc-release: 94 | name: Windows arm64 (LibreSSL) with most recent ponyc release 95 | runs-on: windows-11-arm 96 | steps: 97 | - uses: actions/checkout@v4.1.1 98 | - name: Test with most recent ponyc release 99 | run: | 100 | Invoke-WebRequest https://dl.cloudsmith.io/public/ponylang/nightlies/raw/versions/latest/ponyc-arm64-pc-windows-msvc.zip -OutFile C:\ponyc.zip; 101 | Expand-Archive -Force -Path C:\ponyc.zip -DestinationPath C:\ponyc; 102 | Invoke-WebRequest https://dl.cloudsmith.io/public/ponylang/nightlies/raw/versions/latest/corral-arm64-pc-windows-msvc.zip -OutFile C:\corral.zip; 103 | Expand-Archive -Force -Path C:\corral.zip -DestinationPath C:\ponyc; 104 | $env:PATH = 'C:\ponyc\bin;' + $env:PATH; 105 | .\make.ps1 -Command libs 2>&1; 106 | .\make.ps1 -Command test 2>&1; 107 | -------------------------------------------------------------------------------- /crypto/hash_fn.pony: -------------------------------------------------------------------------------- 1 | use "path:/usr/local/opt/libressl/lib" if osx and x86 2 | use "path:/opt/homebrew/opt/libressl/lib" if osx and arm 3 | use "lib:crypto" 4 | 5 | use @MD4[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8]) 6 | use @MD5[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8]) 7 | use @RIPEMD160[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8]) 8 | use @SHA1[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8]) 9 | use @SHA224[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8]) 10 | use @SHA256[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8]) 11 | use @SHA384[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8]) 12 | use @SHA512[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8]) 13 | 14 | use "format" 15 | 16 | interface HashFn 17 | """ 18 | Produces a fixed-length byte array based on the input sequence. 19 | """ 20 | fun tag apply(input: ByteSeq): Array[U8] val 21 | 22 | primitive MD4 is HashFn 23 | fun tag apply(input: ByteSeq): Array[U8] val => 24 | """ 25 | Compute the MD4 message digest conforming to RFC 1320 26 | """ 27 | recover 28 | let size: USize = 16 29 | let digest = @pony_alloc(@pony_ctx(), size) 30 | @MD4(input.cpointer(), input.size(), digest) 31 | Array[U8].from_cpointer(digest, size) 32 | end 33 | 34 | primitive MD5 is HashFn 35 | fun tag apply(input: ByteSeq): Array[U8] val => 36 | """ 37 | Compute the MD5 message digest conforming to RFC 1321 38 | """ 39 | recover 40 | let size: USize = 16 41 | let digest = @pony_alloc(@pony_ctx(), size) 42 | @MD5(input.cpointer(), input.size(), digest) 43 | Array[U8].from_cpointer(digest, size) 44 | end 45 | 46 | primitive RIPEMD160 is HashFn 47 | fun tag apply(input: ByteSeq): Array[U8] val => 48 | """ 49 | Compute the RIPEMD160 message digest conforming to ISO/IEC 10118-3 50 | """ 51 | recover 52 | let size: USize = 20 53 | let digest = @pony_alloc(@pony_ctx(), size) 54 | @RIPEMD160(input.cpointer(), input.size(), digest) 55 | Array[U8].from_cpointer(digest, size) 56 | end 57 | 58 | primitive SHA1 is HashFn 59 | fun tag apply(input: ByteSeq): Array[U8] val => 60 | """ 61 | Compute the SHA1 message digest conforming to US Federal Information 62 | Processing Standard FIPS PUB 180-4 63 | """ 64 | recover 65 | let size: USize = 20 66 | let digest = @pony_alloc(@pony_ctx(), size) 67 | @SHA1(input.cpointer(), input.size(), digest) 68 | Array[U8].from_cpointer(digest, size) 69 | end 70 | 71 | primitive SHA224 is HashFn 72 | fun tag apply(input: ByteSeq): Array[U8] val => 73 | """ 74 | Compute the SHA224 message digest conforming to US Federal Information 75 | Processing Standard FIPS PUB 180-4 76 | """ 77 | recover 78 | let size: USize = 28 79 | let digest = @pony_alloc(@pony_ctx(), size) 80 | @SHA224(input.cpointer(), input.size(), digest) 81 | Array[U8].from_cpointer(digest, size) 82 | end 83 | 84 | primitive SHA256 is HashFn 85 | fun tag apply(input: ByteSeq): Array[U8] val => 86 | """ 87 | Compute the SHA256 message digest conforming to US Federal Information 88 | Processing Standard FIPS PUB 180-4 89 | """ 90 | recover 91 | let size: USize = 32 92 | let digest = @pony_alloc(@pony_ctx(), size) 93 | @SHA256(input.cpointer(), input.size(), digest) 94 | Array[U8].from_cpointer(digest, size) 95 | end 96 | 97 | primitive SHA384 is HashFn 98 | fun tag apply(input: ByteSeq): Array[U8] val => 99 | """ 100 | Compute the SHA384 message digest conforming to US Federal Information 101 | Processing Standard FIPS PUB 180-4 102 | """ 103 | recover 104 | let size: USize = 48 105 | let digest = @pony_alloc(@pony_ctx(), size) 106 | @SHA384(input.cpointer(), input.size(), digest) 107 | Array[U8].from_cpointer(digest, size) 108 | end 109 | 110 | primitive SHA512 is HashFn 111 | fun tag apply(input: ByteSeq): Array[U8] val => 112 | """ 113 | Compute the SHA512 message digest conforming to US Federal Information 114 | Processing Standard FIPS PUB 180-4 115 | """ 116 | recover 117 | let size: USize = 64 118 | let digest = @pony_alloc(@pony_ctx(), size) 119 | @SHA512(input.cpointer(), input.size(), digest) 120 | Array[U8].from_cpointer(digest, size) 121 | end 122 | 123 | primitive ToHexString 124 | fun tag apply(bs: Array[U8] val): String => 125 | """ 126 | Return the lower-case hexadecimal string representation of the given Array 127 | of U8. 128 | """ 129 | let out = recover String(bs.size() * 2) end 130 | for c in bs.values() do 131 | out.append(Format.int[U8](c where 132 | fmt = FormatHexSmallBare, width = 2, fill = '0')) 133 | end 134 | consume out 135 | -------------------------------------------------------------------------------- /crypto/_test.pony: -------------------------------------------------------------------------------- 1 | use "pony_test" 2 | 3 | actor \nodoc\ Main is TestList 4 | new create(env: Env) => PonyTest(env, this) 5 | new make() => None 6 | 7 | fun tag tests(test: PonyTest) => 8 | test(_TestConstantTimeCompare) 9 | test(_TestMD4) 10 | test(_TestMD5) 11 | test(_TestRIPEMD160) 12 | test(_TestSHA1) 13 | test(_TestSHA224) 14 | test(_TestSHA256) 15 | test(_TestSHA384) 16 | test(_TestSHA512) 17 | test(_TestDigest) 18 | 19 | class \nodoc\ iso _TestConstantTimeCompare is UnitTest 20 | fun name(): String => "crypto/ConstantTimeCompare" 21 | 22 | fun apply(h: TestHelper) => 23 | let s1 = "12345" 24 | let s2 = "54321" 25 | let s3 = "123456" 26 | let s4 = "1234" 27 | let s5 = recover val [as U8: 0; 0; 0; 0; 0] end 28 | let s6 = String.from_array([0; 0; 0; 0; 0]) 29 | let s7 = "" 30 | h.assert_true(ConstantTimeCompare(s1, s1)) 31 | h.assert_false(ConstantTimeCompare(s1, s2)) 32 | h.assert_false(ConstantTimeCompare(s1, s3)) 33 | h.assert_false(ConstantTimeCompare(s1, s4)) 34 | h.assert_false(ConstantTimeCompare(s1, s5)) 35 | h.assert_true(ConstantTimeCompare(s5, s6)) 36 | h.assert_false(ConstantTimeCompare(s1, s6)) 37 | h.assert_false(ConstantTimeCompare(s1, s7)) 38 | 39 | class \nodoc\ iso _TestMD4 is UnitTest 40 | fun name(): String => "crypto/MD4" 41 | 42 | fun apply(h: TestHelper) => 43 | h.assert_eq[String]( 44 | "db346d691d7acc4dc2625db19f9e3f52", 45 | ToHexString(MD4("test"))) 46 | 47 | class \nodoc\ iso _TestMD5 is UnitTest 48 | fun name(): String => "crypto/MD5" 49 | 50 | fun apply(h: TestHelper) => 51 | h.assert_eq[String]( 52 | "098f6bcd4621d373cade4e832627b4f6", 53 | ToHexString(MD5("test"))) 54 | 55 | class \nodoc\ iso _TestRIPEMD160 is UnitTest 56 | fun name(): String => "crypto/RIPEMD160" 57 | 58 | fun apply(h: TestHelper) => 59 | h.assert_eq[String]( 60 | "5e52fee47e6b070565f74372468cdc699de89107", 61 | ToHexString(RIPEMD160("test"))) 62 | 63 | class \nodoc\ iso _TestSHA1 is UnitTest 64 | fun name(): String => "crypto/SHA1" 65 | 66 | fun apply(h: TestHelper) => 67 | h.assert_eq[String]( 68 | "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", 69 | ToHexString(SHA1("test"))) 70 | 71 | class \nodoc\ iso _TestSHA224 is UnitTest 72 | fun name(): String => "crypto/SHA224" 73 | 74 | fun apply(h: TestHelper) => 75 | h.assert_eq[String]( 76 | "90a3ed9e32b2aaf4c61c410eb925426119e1a9dc53d4286ade99a809", 77 | ToHexString(SHA224("test"))) 78 | 79 | class \nodoc\ iso _TestSHA256 is UnitTest 80 | fun name(): String => "crypto/SHA256" 81 | 82 | fun apply(h: TestHelper) => 83 | h.assert_eq[String]( 84 | "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", 85 | ToHexString(SHA256("test"))) 86 | 87 | class \nodoc\ iso _TestSHA384 is UnitTest 88 | fun name(): String => "crypto/SHA384" 89 | 90 | fun apply(h: TestHelper) => 91 | h.assert_eq[String]( 92 | "768412320f7b0aa5812fce428dc4706b3cae50e02a64caa16a782249bfe8efc4" + 93 | "b7ef1ccb126255d196047dfedf17a0a9", 94 | ToHexString(SHA384("test"))) 95 | 96 | class \nodoc\ iso _TestSHA512 is UnitTest 97 | fun name(): String => "crypto/SHA512" 98 | 99 | fun apply(h: TestHelper) => 100 | h.assert_eq[String]( 101 | "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db2" + 102 | "7ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff", 103 | ToHexString(SHA512("test"))) 104 | 105 | class \nodoc\ iso _TestDigest is UnitTest 106 | fun name(): String => "crypto/Digest" 107 | 108 | fun apply(h: TestHelper) ? => 109 | let md5 = Digest.md5() 110 | md5.append("message1")? 111 | md5.append("message2")? 112 | h.assert_eq[String]( 113 | "94af09c09bb9bb7b5c94fec6e6121482", 114 | ToHexString(md5.final())) 115 | 116 | let sha1 = Digest.sha1() 117 | sha1.append("message1")? 118 | sha1.append("message2")? 119 | h.assert_eq[String]( 120 | "942682e2e49f37b4b224fc1aec1a53a25967e7e0", 121 | ToHexString(sha1.final())) 122 | 123 | let sha224 = Digest.sha224() 124 | sha224.append("message1")? 125 | sha224.append("message2")? 126 | h.assert_eq[String]( 127 | "fbba013f116e8b09b044b2a785ed7fb6a65ce672d724c1fb20500d45", 128 | ToHexString(sha224.final())) 129 | 130 | let sha256 = Digest.sha256() 131 | sha256.append("message1")? 132 | sha256.append("message2")? 133 | h.assert_eq[String]( 134 | "68d9b867db4bde630f3c96270b2320a31a72aafbc39997eb2bc9cf2da21e5213", 135 | ToHexString(sha256.final())) 136 | 137 | let sha384 = Digest.sha384() 138 | sha384.append("message1")? 139 | sha384.append("message2")? 140 | h.assert_eq[String]( 141 | "7736dd67494a7072bf255852bd327406b398cb0b16cb400fcd3fcfb6827d74ab"+ 142 | "9b14673d50515b6273ef15543325f8d3", 143 | ToHexString(sha384.final())) 144 | 145 | let sha512 = Digest.sha512() 146 | sha512.append("message1")? 147 | sha512.append("message2")? 148 | h.assert_eq[String]( 149 | "3511f4825021a90cd55d37db5c3250e6bbcffc9a0d56d88b4e2878ac5b094692"+ 150 | "cd945c6a77006272322f911c9be31fa970043daa4b61cee607566cbfa2c69b09", 151 | ToHexString(sha512.final())) 152 | 153 | ifdef "openssl_1.1.x" or "openssl_3.0.x" then 154 | let shake128 = Digest.shake128() 155 | shake128.append("message1")? 156 | shake128.append("message2")? 157 | h.assert_eq[String]( 158 | "0d11671f23b6356bdf4ba8dcae37419d", 159 | ToHexString(shake128.final())) 160 | 161 | let shake256 = Digest.shake256() 162 | shake256.append("message1")? 163 | shake256.append("message2")? 164 | h.assert_eq[String]( 165 | "80e2bbb14639e3b1fc1df80b47b67fb518b0ed26a1caddfa10d68f7992c33820", 166 | ToHexString(shake256.final())) 167 | end 168 | -------------------------------------------------------------------------------- /crypto/digest.pony: -------------------------------------------------------------------------------- 1 | use "path:/usr/local/opt/libressl/lib" if osx and x86 2 | use "path:/opt/homebrew/opt/libressl/lib" if osx and arm 3 | use "lib:crypto" 4 | use "lib:bcrypt" if windows 5 | 6 | use @EVP_MD_CTX_new[Pointer[_EVPCTX]]() if "openssl_1.1.x" or "openssl_3.0.x" 7 | use @EVP_MD_CTX_create[Pointer[_EVPCTX]]() if not "openssl_1.1.x" or "openssl_3.0.x" 8 | use @EVP_DigestInit_ex[I32](ctx: Pointer[_EVPCTX] tag, t: Pointer[_EVPMD], impl: USize) 9 | use @EVP_DigestUpdate[I32](ctx: Pointer[_EVPCTX] tag, d: Pointer[U8] tag, cnt: USize) 10 | use @EVP_DigestFinal_ex[I32](ctx: Pointer[_EVPCTX] tag, md: Pointer[U8] tag, s: Pointer[USize]) 11 | use @EVP_MD_CTX_free[None](ctx: Pointer[_EVPCTX]) if "openssl_1.1.x" or "openssl_3.0.x" 12 | use @EVP_MD_CTX_destroy[None](ctx: Pointer[_EVPCTX]) if not "openssl_1.1.x" or "openssl_3.0.x" 13 | 14 | use @EVP_md5[Pointer[_EVPMD]]() 15 | use @EVP_ripemd160[Pointer[_EVPMD]]() 16 | use @EVP_sha1[Pointer[_EVPMD]]() 17 | use @EVP_sha224[Pointer[_EVPMD]]() 18 | use @EVP_sha256[Pointer[_EVPMD]]() 19 | use @EVP_sha384[Pointer[_EVPMD]]() 20 | use @EVP_sha512[Pointer[_EVPMD]]() 21 | use @EVP_shake128[Pointer[_EVPMD]]() 22 | use @EVP_shake256[Pointer[_EVPMD]]() 23 | 24 | primitive _EVPMD 25 | primitive _EVPCTX 26 | 27 | class Digest 28 | """ 29 | Produces a hash from the chunks of input. Feed the input with append() and 30 | produce a final hash from the concatenation of the input with final(). 31 | """ 32 | let _digest_size: USize 33 | let _ctx: Pointer[_EVPCTX] 34 | var _hash: (Array[U8] val | None) = None 35 | 36 | new md5() => 37 | """ 38 | Use the MD5 algorithm to calculate the hash. 39 | """ 40 | _digest_size = 16 41 | ifdef "openssl_1.1.x" or "openssl_3.0.x" then 42 | _ctx = @EVP_MD_CTX_new() 43 | else 44 | _ctx = @EVP_MD_CTX_create() 45 | end 46 | @EVP_DigestInit_ex(_ctx, @EVP_md5(), USize(0)) 47 | 48 | new ripemd160() => 49 | """ 50 | Use the RIPEMD160 algorithm to calculate the hash. 51 | """ 52 | _digest_size = 20 53 | ifdef "openssl_1.1.x" or "openssl_3.0.x" then 54 | _ctx = @EVP_MD_CTX_new() 55 | else 56 | _ctx = @EVP_MD_CTX_create() 57 | end 58 | @EVP_DigestInit_ex(_ctx, @EVP_ripemd160(), USize(0)) 59 | 60 | new sha1() => 61 | """ 62 | Use the SHA1 algorithm to calculate the hash. 63 | """ 64 | _digest_size = 20 65 | ifdef "openssl_1.1.x" or "openssl_3.0.x" then 66 | _ctx = @EVP_MD_CTX_new() 67 | else 68 | _ctx = @EVP_MD_CTX_create() 69 | end 70 | @EVP_DigestInit_ex(_ctx, @EVP_sha1(), USize(0)) 71 | 72 | new sha224() => 73 | """ 74 | Use the SHA256 algorithm to calculate the hash. 75 | """ 76 | _digest_size = 28 77 | ifdef "openssl_1.1.x" or "openssl_3.0.x" then 78 | _ctx = @EVP_MD_CTX_new() 79 | else 80 | _ctx = @EVP_MD_CTX_create() 81 | end 82 | @EVP_DigestInit_ex(_ctx, @EVP_sha224(), USize(0)) 83 | 84 | new sha256() => 85 | """ 86 | Use the SHA256 algorithm to calculate the hash. 87 | """ 88 | _digest_size = 32 89 | ifdef "openssl_1.1.x" or "openssl_3.0.x" then 90 | _ctx = @EVP_MD_CTX_new() 91 | else 92 | _ctx = @EVP_MD_CTX_create() 93 | end 94 | @EVP_DigestInit_ex(_ctx, @EVP_sha256(), USize(0)) 95 | 96 | new sha384() => 97 | """ 98 | Use the SHA384 algorithm to calculate the hash. 99 | """ 100 | _digest_size = 48 101 | ifdef "openssl_1.1.x" or "openssl_3.0.x" then 102 | _ctx = @EVP_MD_CTX_new() 103 | else 104 | _ctx = @EVP_MD_CTX_create() 105 | end 106 | @EVP_DigestInit_ex(_ctx, @EVP_sha384(), USize(0)) 107 | 108 | new sha512() => 109 | """ 110 | Use the SHA512 algorithm to calculate the hash. 111 | """ 112 | _digest_size = 64 113 | ifdef "openssl_1.1.x" or "openssl_3.0.x" then 114 | _ctx = @EVP_MD_CTX_new() 115 | else 116 | _ctx = @EVP_MD_CTX_create() 117 | end 118 | @EVP_DigestInit_ex(_ctx, @EVP_sha512(), USize(0)) 119 | 120 | new shake128() => 121 | """ 122 | Use the Shake128 algorithm to calculate the hash. 123 | """ 124 | _digest_size = 16 125 | ifdef "openssl_1.1.x" or "openssl_3.0.x" then 126 | _ctx = @EVP_MD_CTX_new() 127 | @EVP_DigestInit_ex(_ctx, @EVP_shake128(), USize(0)) 128 | else 129 | compile_error "openssl_0.9.x dose not support shake128" 130 | end 131 | 132 | new shake256() => 133 | """ 134 | Use the Shake256 algorithm to calculate the hash. 135 | """ 136 | _digest_size = 32 137 | ifdef "openssl_1.1.x" or "openssl_3.0.x" then 138 | _ctx = @EVP_MD_CTX_new() 139 | @EVP_DigestInit_ex(_ctx, @EVP_shake256(), USize(0)) 140 | else 141 | compile_error "openssl_0.9.x dose not support shake256" 142 | end 143 | 144 | fun ref append(input: ByteSeq) ? => 145 | """ 146 | Update the Digest object with input. Throw an error if final() has been 147 | called. 148 | """ 149 | if _hash isnt None then error end 150 | @EVP_DigestUpdate(_ctx, input.cpointer(), input.size()) 151 | 152 | fun ref final(): Array[U8] val => 153 | """ 154 | Return the digest of the strings passed to the append() method. 155 | """ 156 | match _hash 157 | | let h: Array[U8] val => h 158 | else 159 | let size = _digest_size 160 | let digest = 161 | recover String.from_cpointer( 162 | @pony_alloc(@pony_ctx(), size), size) 163 | end 164 | @EVP_DigestFinal_ex(_ctx, digest.cpointer(), Pointer[USize]) 165 | ifdef "openssl_1.1.x" or "openssl_3.0.x" then 166 | @EVP_MD_CTX_free(_ctx) 167 | else 168 | @EVP_MD_CTX_destroy(_ctx) 169 | end 170 | let h = (consume digest).array() 171 | _hash = h 172 | h 173 | end 174 | 175 | fun digest_size(): USize => 176 | """ 177 | Return the size of the message digest in bytes. 178 | """ 179 | _digest_size 180 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project maintainers at coc@ponylang.io. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | 48 | # Social Rules 49 | 50 | In addition to having a code of conduct as an anti-harassment policy, we have a small set of [social rules](https://www.recurse.com/manual#sub-sec-social-rules) we follow. We (the project maintainers) lifted these rules from the [Recurse Center](https://www.recurse.com). We've seen these rules in effect in other environments. We'd like the Pony community to share a similar positive environment. These rules are intended to be lightweight, and to make more explicit certain social norms that are normally implicit. Most of our social rules really boil down to “don't be a jerk” or “don't be annoying.” Of course, almost nobody sets out to be a jerk or annoying, so telling people not to be jerks isn't a very productive strategy. 51 | 52 | Unlike the anti-harassment policy, violation of the social rules will not result in expulsion from the Pony community or a strong warning from project maintainers. Rather, they are designed to provide some lightweight social structure for community members to use when interacting with each other. 53 | 54 | ## No feigning surprise. 55 | 56 | The first rule means you shouldn't act surprised when people say they don't know something. This applies to both technical things ("What?! I can't believe you don't know what the stack is!") and non-technical things ("You don't know who RMS is?!"). Feigning surprise has absolutely no social or educational benefit: When people feign surprise, it's usually to make them feel better about themselves and others feel worse. And even when that's not the intention, it's almost always the effect. 57 | 58 | ## No well-actually's 59 | 60 | A well-actually happens when someone says something that's almost - but not entirely - correct, and you say, "well, actually…" and then give a minor correction. This is especially annoying when the correction has no bearing on the actual conversation. This doesn't mean we aren't about truth-seeking or that we don't care about being precise. Almost all well-actually's in our experience are about grandstanding, not truth-seeking. 61 | 62 | ## No subtle -isms 63 | 64 | Our last social rule bans subtle racism, sexism, homophobia, transphobia, and other kinds of bias. This one is different from the rest, because it covers a class of behaviors instead of one very specific pattern. 65 | 66 | Subtle -isms are small things that make others feel uncomfortable, things that we all sometimes do by mistake. For example, saying "It's so easy my grandmother could do it" is a subtle -ism. Like the other three social rules, this one is often accidentally broken. Like the other three, it's not a big deal to mess up – you just apologize and move on. 67 | 68 | If you see a subtle -ism in the Pony community, you can point it out to the relevant person, either publicly or privately, or you can ask one of the project maintainers to say something. After this, we ask that all further discussion move off of public channels. If you are a third party, and you don't see what could be biased about the comment that was made, feel free to talk to the project maintainers. Please don't say, "Comment X wasn't homophobic!" Similarly, please don't pile on to someone who made a mistake. The "subtle" in "subtle -isms" means that it's probably not obvious to everyone right away what was wrong with the comment. 69 | 70 | If you have any questions about any part of the code of conduct or social rules, please feel free to reach out to any of the project maintainers. 71 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | You want to contribute to crypto? Awesome. 4 | 5 | There are a number of ways to contribute. As this document is a little long, feel free to jump to the section that applies to you currently: 6 | 7 | * [Bug report](#bug-report) 8 | * [How to contribute](#how-to-contribute) 9 | * [Pull request](#pull-request) 10 | 11 | Additional notes regarding formatting: 12 | 13 | * [Documentation formatting](#documentation-formatting) 14 | * [Code formatting](#code-formatting) 15 | * [File naming](#file-naming) 16 | 17 | ## Bug report 18 | 19 | First of all please [search existing issues](https://github.com/ponylang/crypto/issues) to make sure your issue hasn't already been reported. If you cannot find a suitable issue — [create a new one](https://github.com/ponylang/crypto/issues/new). 20 | 21 | Provide the following details: 22 | 23 | * short summary of what you were trying to achieve, 24 | * a code snippet causing the bug, 25 | * expected result, 26 | * actual results and 27 | * environment details: at least operating system version 28 | 29 | If possible, try to isolate the problem and provide just enough code to demonstrate it. Add any related information which might help to fix the issue. 30 | 31 | ## How to contribute 32 | 33 | This project uses a fairly standard GitHub pull request workflow. If you have already contributed to a project via GitHub pull request, you can skip this section and proceed to the [specific details of what we ask for in a pull request](#pull-request). If this is your first time contributing to a project via GitHub, read on. 34 | 35 | Here is the basic GitHub workflow: 36 | 37 | 1. Fork this repo. you can do this via the GitHub website. This will result in you having your own copy of the repo under your GitHub account. 38 | 2. Clone your forked repo to your local machine 39 | 3. Make a branch for your change 40 | 4. Make your change on that branch 41 | 5. Push your change to your repo 42 | 6. Use the github ui to open a PR 43 | 44 | Some things to note that aren't immediately obvious to folks just starting out: 45 | 46 | 1. Your fork doesn't automatically stay up to date with changes in the main repo. 47 | 2. Any changes you make on your branch that you used for one PR will automatically appear in another PR so if you have more than 1 PR, be sure to always create different branches for them. 48 | 3. Weird things happen with commit history if you don't create your PR branches off of `main` so always make sure you have the `main` branch checked out before creating a branch for a PR 49 | 50 | You can get help using GitHub via [the official documentation](https://help.github.com/). Some highlights include: 51 | 52 | * [Fork A Repo](https://help.github.com/articles/fork-a-repo/) 53 | * [Creating a pull request](https://help.github.com/articles/creating-a-pull-request/) 54 | * [Syncing a fork](https://help.github.com/articles/syncing-a-fork/) 55 | 56 | ## Pull request 57 | 58 | While we don't require that your pull request be a single commit, note that we will end up squashing all your commits into a single commit when we merge. While your PR is in review, we may ask for additional changes, please do not squash those commits while the review is underway. We ask that you not squash while a review is underway as it can make it hard to follow what is going on. 59 | 60 | When opening your pull request, please make sure that the initial comment on the PR is the commit message we should use when we merge. Making sure your commit message conforms to these guidelines for [writ(ing) a good commit message](http://chris.beams.io/posts/git-commit/). 61 | 62 | Make sure to issue 1 pull request per feature. Don't lump unrelated changes together. If you find yourself using the word "and" in your commit comment, you 63 | are probably doing too much for a single PR. 64 | 65 | We keep a [CHANGELOG](CHANGELOG.md) of all software changes with behavioural effects in ponyc. If your PR includes such changes (rather than say a documentation update), a Pony team member will do the following before merging it, so that the PR will be automatically added to the CHANGELOG: 66 | 67 | * Ensure that the ticket is tagged with one or more appropriate "changelog - *" labels - each label corresponds to a section of the changelog where this change will be automatically mentioned. 68 | * Ensure that the ticket title is appropriate - the title will be used as the summary of the change, so it should be appropriately formatted, including a ticket reference if the PR is a fix to an existing bug ticket. 69 | * For example, an appropriate title for a PR that fixes a bug reported in issue ticket #98 might look like: 70 | * *Fixed compiler crash related to tuple recovery (issue #98)* 71 | 72 | Once those conditions are met, the PR can be merged, and an automated system will immediately add the entry to the changelog. Keeping the changelog entries out of the file changes in the PR helps to avoid conflicts and other administrative headaches when many PRs are in progress. 73 | 74 | Any change that involves a changelog entry will trigger a bot to request that you add release notes to your PR. 75 | 76 | Pull requests from accounts that aren't members of the Ponylang organization require approval from a member before running. Approval is required after each update that you make. This could involve a lot of waiting on your part for approvals. If you are opening PRs to verify that changes all pass CI before "opening it for real", we strongly suggest that you open the PR against the `main` branch of your fork. CI will then run in your fork and you don't need to wait for approval from a Ponylang member. 77 | 78 | ## Documentation formatting 79 | 80 | When contributing to documentation, try to keep the following style guidelines in mind: 81 | 82 | As much as possible all documentation should be textual and in Markdown format. Diagrams are often needed to clarify a point. For any images, an original high-resolution source should be provided as well so updates can be made. 83 | 84 | Documentation is not "source code." As such, it should not be wrapped at 80 columns. Documentation should be allowed to flow naturally until the end of a paragraph. It is expected that the reader will turn on soft wrapping as needed. 85 | 86 | All code examples in documentation should be formatted in a fashion appropriate to the language in question. 87 | 88 | All command line examples in documentation should be presented in a copy and paste friendly fashion. Assume the user is using the `bash` shell. GitHub formatting on long command lines can be unfriendly to copy-and-paste. Long command lines should be broken up using `\` so that each line is no more than 80 columns. Wrapping at 80 columns should result in a good display experience in GitHub. Additionally, continuation lines should be indented two spaces. 89 | 90 | OK: 91 | 92 | ```bash 93 | my_command --some-option foo --path-to-file ../../project/long/line/foo \ 94 | --some-other-option bar 95 | ``` 96 | 97 | Not OK: 98 | 99 | ```bash 100 | my_command --some-option foo --path-to-file ../../project/long/line/foo --some-other-option bar 101 | ``` 102 | 103 | Wherever possible when writing documentation, favor full command options rather than short versions. Full flags are usually much easier to modify because the meaning is clearer. 104 | 105 | OK: 106 | 107 | ```bash 108 | my_command --messages 100 109 | ``` 110 | 111 | Not OK: 112 | 113 | ```bash 114 | my_command -m 100 115 | ``` 116 | 117 | ## Code formatting 118 | 119 | The basics: 120 | 121 | * Indentation 122 | 123 | Indent using spaces, not tabs. Indentation is language specific. 124 | 125 | * Watch your whitespace! 126 | 127 | Use an editor plugin to remove unused trailing whitespace including both at the end of a line and at the end of a file. By the same token, remember to leave a single newline only line at the end of each file. It makes output files to the console much more pleasant. 128 | 129 | * Line Length 130 | 131 | We all have different sized monitors. What might look good on yours might look like awful on another. Be kind and wrap all lines at 80 columns unless you have a good reason not to. 132 | 133 | * Reformatting code to meet standards 134 | 135 | Try to avoid doing it. A commit that changes the formatting for large chunks of a file makes for an ugly commit history when looking for changes. Don't commit code that doesn't conform to coding standards in the first place. If you do reformat code, make sure it is either standalone reformatting with no logic changes or confined solely to code whose logic you touched. For example, updating the indentation in a file? Do not make logic changes along with it. Editing a line that has extra whitespace at the end? Feel free to remove it. 136 | 137 | The details: 138 | 139 | All Pony sources should follow the [Pony standard library style guide](https://github.com/ponylang/ponyc/blob/main/STYLE_GUIDE.md). 140 | 141 | ## File naming 142 | 143 | Pony code follows the [Pony standard library file naming guidelines](https://github.com/ponylang/ponyc/blob/main/STYLE_GUIDE.md#naming). 144 | -------------------------------------------------------------------------------- /make.ps1: -------------------------------------------------------------------------------- 1 | Param( 2 | [Parameter(Position=0, HelpMessage="The action to take (build, test, install, package, clean).")] 3 | [string] 4 | $Command = 'build', 5 | 6 | [Parameter(HelpMessage="The build configuration (Release, Debug).")] 7 | [string] 8 | $Config = "Release", 9 | 10 | [Parameter(HelpMessage="The version number to set.")] 11 | [string] 12 | $Version = "", 13 | 14 | [Parameter(HelpMessage="Architecture (native, x64).")] 15 | [string] 16 | $Arch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture, 17 | 18 | [Parameter(HelpMessage="Directory to install to.")] 19 | [string] 20 | $Destdir = "build/install" 21 | ) 22 | 23 | $ErrorActionPreference = "Stop" 24 | 25 | $target = "crypto" # The name of the source package, and the base name of the .exe file that is built if this is a program, not a library. 26 | $testPath = "." # The path of the tests package relative to the $target directory. 27 | $isLibrary = $true 28 | 29 | $rootDir = Split-Path $script:MyInvocation.MyCommand.Path 30 | $srcDir = Join-Path -Path $rootDir -ChildPath $target 31 | 32 | 33 | if ($Arch -ieq 'x64') 34 | { 35 | $Arch = 'x86-64' 36 | } 37 | elseif ($Arch -ieq 'arm64') 38 | { 39 | $Arch = 'arm64' 40 | } 41 | 42 | $Thost = "x64" 43 | if ($Arch -ieq "arm64") 44 | { 45 | # if this is lowercase arm64, then things go boom. 46 | $Thost = "ARM64" 47 | } 48 | 49 | if ($Config -ieq "Release") 50 | { 51 | $configFlag = "" 52 | $buildDir = Join-Path -Path $rootDir -ChildPath "build/release" 53 | } 54 | elseif ($Config -ieq "Debug") 55 | { 56 | $configFlag = "--debug" 57 | $buildDir = Join-Path -Path $rootDir -ChildPath "build/debug" 58 | } 59 | else 60 | { 61 | throw "Invalid -Config path '$Config'; must be one of (Debug, Release)." 62 | } 63 | 64 | $libsDir = Join-Path -Path $rootDir -ChildPath "build/libs" 65 | 66 | if (($Version -eq "") -and (Test-Path -Path "$rootDir\VERSION")) 67 | { 68 | $Version = (Get-Content "$rootDir\VERSION") + "-" + (& git 'rev-parse' '--short' '--verify' 'HEAD^') 69 | } 70 | 71 | $ponyArgs = "--define openssl_0.9.0 --path $rootDir" 72 | 73 | Write-Host "Configuration: $Config" 74 | Write-Host "Version: $Version" 75 | Write-Host "Root directory: $rootDir" 76 | Write-Host "Source directory: $srcDir" 77 | Write-Host "Build directory: $buildDir" 78 | 79 | # generate pony templated files if necessary 80 | if (($Command -ne "clean") -and (Test-Path -Path "$rootDir\VERSION")) 81 | { 82 | $versionTimestamp = (Get-ChildItem -Path "$rootDir\VERSION").LastWriteTimeUtc 83 | Get-ChildItem -Path $srcDir -Include "*.pony.in" -Recurse | ForEach-Object { 84 | $templateFile = $_.FullName 85 | $ponyFile = $templateFile.Substring(0, $templateFile.Length - 3) 86 | $ponyFileTimestamp = [DateTime]::MinValue 87 | if (Test-Path $ponyFile) 88 | { 89 | $ponyFileTimestamp = (Get-ChildItem -Path $ponyFile).LastWriteTimeUtc 90 | } 91 | if (($ponyFileTimestamp -lt $versionTimestamp) -or ($ponyFileTimestamp -lt $_.LastWriteTimeUtc)) 92 | { 93 | Write-Host "$templateFile -> $ponyFile" 94 | ((Get-Content -Path $templateFile) -replace '%%VERSION%%', $Version) | Set-Content -Path $ponyFile 95 | } 96 | } 97 | } 98 | 99 | function BuildTarget 100 | { 101 | $binaryFile = Join-Path -Path $buildDir -ChildPath "$target.exe" 102 | $binaryTimestamp = [DateTime]::MinValue 103 | if (Test-Path $binaryFile) 104 | { 105 | $binaryTimestamp = (Get-ChildItem -Path $binaryFile).LastWriteTimeUtc 106 | } 107 | 108 | :buildFiles foreach ($file in (Get-ChildItem -Path $srcDir -Include "*.pony" -Recurse)) 109 | { 110 | if ($binaryTimestamp -lt $file.LastWriteTimeUtc) 111 | { 112 | Write-Host "corral fetch" 113 | $output = (corral fetch) 114 | $output | ForEach-Object { Write-Host $_ } 115 | if ($LastExitCode -ne 0) { throw "Error" } 116 | 117 | Write-Host "corral run -- ponyc $configFlag $ponyArgs --output `"$buildDir`" `"$srcDir`"" 118 | $output = (corral run -- ponyc $configFlag $ponyArgs --output "$buildDir" "$srcDir") 119 | $output | ForEach-Object { Write-Host $_ } 120 | if ($LastExitCode -ne 0) { throw "Error" } 121 | break buildFiles 122 | } 123 | } 124 | } 125 | 126 | function BuildTest 127 | { 128 | $testTarget = "test.exe" 129 | if ($testPath -eq ".") 130 | { 131 | $testTarget = "$target.exe" 132 | } 133 | 134 | $testFile = Join-Path -Path $buildDir -ChildPath $testTarget 135 | $testTimestamp = [DateTime]::MinValue 136 | if (Test-Path $testFile) 137 | { 138 | $testTimestamp = (Get-ChildItem -Path $testFile).LastWriteTimeUtc 139 | } 140 | 141 | :testFiles foreach ($file in (Get-ChildItem -Path $srcDir -Include "*.pony" -Recurse)) 142 | { 143 | if ($testTimestamp -lt $file.LastWriteTimeUtc) 144 | { 145 | Write-Host "corral fetch" 146 | $output = (corral fetch) 147 | $output | ForEach-Object { Write-Host $_ } 148 | if ($LastExitCode -ne 0) { throw "Error" } 149 | 150 | $testDir = Join-Path -Path $srcDir -ChildPath $testPath 151 | Write-Host "corral run -- ponyc $configFlag $ponyArgs --output `"$buildDir`" `"$testDir`"" 152 | $output = (corral run -- ponyc $configFlag $ponyArgs --output "$buildDir" "$testDir") 153 | $output | ForEach-Object { Write-Host $_ } 154 | if ($LastExitCode -ne 0) { throw "Error" } 155 | break testFiles 156 | } 157 | } 158 | 159 | Write-Output "$testTarget.exe is built" # force function to return a list of outputs 160 | return $testFile 161 | } 162 | 163 | function BuildLibs 164 | { 165 | $libreSsl = "libressl-3.9.1" 166 | 167 | if (-not (Test-Path "$rootDir/crypto.lib")) 168 | { 169 | $libreSslSrc = Join-Path -Path $libsDir -ChildPath $libreSsl 170 | 171 | if (-not (Test-Path $libreSslSrc)) 172 | { 173 | $libreSslTgz = "$libreSsl.tar.gz" 174 | $libreSslTgzTgt = Join-Path -Path $libsDir -ChildPath $libreSslTgz 175 | if (-not (Test-Path $libreSslTgzTgt)) { Invoke-WebRequest -TimeoutSec 300 -Uri "https://cdn.openbsd.org/pub/OpenBSD/LibreSSL/$libreSslTgz" -OutFile $libreSslTgzTgt } 176 | tar -xvzf "$libreSslTgzTgt" -C "$libsDir" 177 | if ($LastExitCode -ne 0) { throw "Error downloading and extracting $libreSslTgz" } 178 | } 179 | 180 | # Write-Output "Building $libreSsl" 181 | $libreSslLib = Join-Path -Path $libsDir -ChildPath "lib/ssl-48.lib" 182 | 183 | if (-not (Test-Path $libreSslLib)) 184 | { 185 | Push-Location $libreSslSrc 186 | (Get-Content "$libreSslSrc\CMakeLists.txt").replace('add_definitions(-Dinline=__inline)', "add_definitions(-Dinline=__inline)`nadd_definitions(-DPATH_MAX=255)") | Set-Content "$libreSslSrc\CMakeLists.txt" 187 | cmake.exe $libreSslSrc -Thost="$Thost" -A "$THost" -DCMAKE_INSTALL_PREFIX="$libsDir" -DCMAKE_BUILD_TYPE="Release" 188 | if ($LastExitCode -ne 0) { Pop-Location; throw "Error configuring $libreSsl" } 189 | cmake.exe --build . --target install --config Release 190 | if ($LastExitCode -ne 0) { Pop-Location; throw "Error building $libreSsl" } 191 | Pop-Location 192 | } 193 | 194 | # copy to the root dir (i.e. PONYPATH) for linking 195 | Copy-Item -Force -Path "$libsDir/lib/crypto.lib" -Destination "$rootDir/crypto.lib" 196 | } 197 | } 198 | 199 | switch ($Command.ToLower()) 200 | { 201 | "libs" 202 | { 203 | if (-not (Test-Path $libsDir)) 204 | { 205 | mkdir "$libsDir" 206 | } 207 | 208 | BuildLibs 209 | } 210 | 211 | "build" 212 | { 213 | if (-not $isLibrary) 214 | { 215 | BuildTarget 216 | } 217 | else 218 | { 219 | Write-Host "$target is a library; nothing to build." 220 | } 221 | break 222 | } 223 | 224 | "test" 225 | { 226 | if (-not $isLibrary) 227 | { 228 | BuildTarget 229 | } 230 | 231 | $testFile = (BuildTest)[-1] 232 | Write-Host "$testFile" 233 | & "$testFile" 234 | if ($LastExitCode -ne 0) { throw "Error" } 235 | break 236 | } 237 | 238 | "clean" 239 | { 240 | if (Test-Path "$buildDir") 241 | { 242 | Write-Host "Remove-Item -Path `"$buildDir`" -Recurse -Force" 243 | Remove-Item -Path "$buildDir" -Recurse -Force 244 | } 245 | break 246 | } 247 | 248 | "distclean" 249 | { 250 | $distDir = Join-Path -Path $rootDir -ChildPath "build" 251 | if (Test-Path $distDir) 252 | { 253 | Remove-Item -Path $distDir -Recurse -Force 254 | } 255 | Remove-Item -Path "*.lib" -Force 256 | } 257 | 258 | "install" 259 | { 260 | if (-not $isLibrary) 261 | { 262 | $binDir = Join-Path -Path $Destdir -ChildPath "bin" 263 | 264 | if (-not (Test-Path $binDir)) 265 | { 266 | mkdir "$binDir" 267 | } 268 | 269 | $binFile = Join-Path -Path $buildDir -ChildPath "$target.exe" 270 | Copy-Item -Path $binFile -Destination $binDir -Force 271 | } 272 | else 273 | { 274 | Write-Host "$target is a library; nothing to install." 275 | } 276 | break 277 | } 278 | 279 | "package" 280 | { 281 | if (-not $isLibrary) 282 | { 283 | $binDir = Join-Path -Path $Destdir -ChildPath "bin" 284 | $package = "$target-$Arch-pc-windows-msvc.zip" 285 | Write-Host "Creating $package..." 286 | 287 | Compress-Archive -Path $binDir -DestinationPath "$buildDir\..\$package" -Force 288 | } 289 | else 290 | { 291 | Write-Host "$target is a library; nothing to package." 292 | } 293 | break 294 | } 295 | 296 | default 297 | { 298 | throw "Unknown command '$Command'; must be one of (libs, build, test, install, package, clean, distclean)." 299 | } 300 | } 301 | --------------------------------------------------------------------------------