FOSS Resists Extralegal Executive Overreaching Nations - Threshold digital signature library in Go
Go
106
57 commits
updated Sep 2, 2025
FOSS Resists Extralegal Executive Overreaching Nations
FREEON implements FROST (RFC 9591) to allow geographically distributed teams produce digital signatures.
Each share of the signing key is encrypted locally using age.
[!WARNING] This software is a minimum viable product (MVP) and is only in the alpha stage of development. It has not been audited. Do not use this in production yet!
This project is not affiliated with the Chemours Company.
go install github.com/soatok/freeon/client@latest
You can also clone the repository to install the client locally:
git clone https://github.com/soatok/freeon.git
cd freeon/client
go install
[!WARNING] The coordinator is expected to run on a private network, such as Tailscale, ZeroTier, or within a Virtual Private Cloud (VPC) from AWS, Azure, or GCP.
In the future, we will develop a standalone coordinator that can safely be deployed on the public-facing Internet, but this was cut from the alpha release due to time constraints.
git clone https://github.com/soatok/freeon.git
cd freeon
go build -o coordinator ./coordinator
./coordinator
The order of operations is as followed:
We will document each command in tandem with this order of operations.
To initiate a new DKG group, one of the clients with access to the coordinator will run the following command (replace 7 and 3 with the number of participants and threshold needed to perform a signature operation, respectively):
freeon keygen create -h hostname:port -n 7 -t 3
Upon success, a Group ID will be returned. This is to be shared with the other participants, who will pass it as an extra argument:
freeon keygen join -h hostname:port -g [group-id-goes-here]
This will maintain a connection with the coordinator until all n participants have connected. Afterwards, a copy of the public key will be returned to each client.
If you provide a public key (-r [RECIPIENT]) as an optional argument, the Freeon client will use age to encrypt the share locally. This public key can be an age public key or an OpenSSH public key.
To initiate a key ceremony, the following information is needed:
The message can be passed as a file name or via STDIN, like so:
freeon sign create -g [group-id-goes-here] file-with-message.txt
echo -n "MESSAGE TO BE SIGNED" | freeon sign create -g [group-id-goes-here]
This will initialize a signature in progress and return a Ceremony ID.
[!NOTE] You do not need a key share to initiate a signature proposal. This is an intentional design feature to allow CI/CD pipelines queue up a Signature Ceremony that clients can then opt into participating in.
By default, the final signature will be returned as a 128-character hex-encoded string (encoded as R || z).
You can pass an optional --openssh flag to return an OpenSSH-compatible signature.
freeon sign create --openssh -g [group-id-goes-here] file-with-message.txt
echo -n "MESSAGE TO BE SIGNED" | freeon sign create --openssh -g [group-id-goes-here]
You can run this command to flush any incomplete ceremonies.
freeon terminate [ceremony-id-goes-here]
[!WARNING] You do not need privileged access to perform this step.
Each client will need to run this command to participate in the ceremony.
freeon sign join -c [ceremony-id] file-with-message.txt
echo -n "MESSAGE TO BE SIGNED" | freeon sign join -c [ceremony-id]
# Identical:
freeon sign join --ceremony [ceremony-id] file-with-message.txt
echo -n "MESSAGE TO BE SIGNED" | freeon sign join --ceremony [ceremony-id]
You can furthermore pass the -i or --identity flag to specify the file path for your age secret keys.
freeon sign join -c [ceremony-id] -i /path/to/age.keys file-with-message.txt
echo -n "MESSAGE TO BE SIGNED" | freeon sign join -i /path/to/age.keys -c [ceremony-id]
# Identical
freeon sign join --ceremony [ceremony-id] --identity /path/to/age.keys file-with-message.txt
echo -n "MESSAGE TO BE SIGNED" | freeon sign join --identity /path/to/age.keys --ceremony [ceremony-id]
57 commits
Go
100.0%
FOSS Resists Extralegal Executive Overreaching Nations - Threshold digital signature library in Go
Go
106
57 commits
updated Sep 2, 2025
FOSS Resists Extralegal Executive Overreaching Nations
FREEON implements FROST (RFC 9591) to allow geographically distributed teams produce digital signatures.
Each share of the signing key is encrypted locally using age.
[!WARNING] This software is a minimum viable product (MVP) and is only in the alpha stage of development. It has not been audited. Do not use this in production yet!
This project is not affiliated with the Chemours Company.
go install github.com/soatok/freeon/client@latest
You can also clone the repository to install the client locally:
git clone https://github.com/soatok/freeon.git
cd freeon/client
go install
[!WARNING] The coordinator is expected to run on a private network, such as Tailscale, ZeroTier, or within a Virtual Private Cloud (VPC) from AWS, Azure, or GCP.
In the future, we will develop a standalone coordinator that can safely be deployed on the public-facing Internet, but this was cut from the alpha release due to time constraints.
git clone https://github.com/soatok/freeon.git
cd freeon
go build -o coordinator ./coordinator
./coordinator
The order of operations is as followed:
We will document each command in tandem with this order of operations.
To initiate a new DKG group, one of the clients with access to the coordinator will run the following command (replace 7 and 3 with the number of participants and threshold needed to perform a signature operation, respectively):
freeon keygen create -h hostname:port -n 7 -t 3
Upon success, a Group ID will be returned. This is to be shared with the other participants, who will pass it as an extra argument:
freeon keygen join -h hostname:port -g [group-id-goes-here]
This will maintain a connection with the coordinator until all n participants have connected. Afterwards, a copy of the public key will be returned to each client.
If you provide a public key (-r [RECIPIENT]) as an optional argument, the Freeon client will use age to encrypt the share locally. This public key can be an age public key or an OpenSSH public key.
To initiate a key ceremony, the following information is needed:
The message can be passed as a file name or via STDIN, like so:
freeon sign create -g [group-id-goes-here] file-with-message.txt
echo -n "MESSAGE TO BE SIGNED" | freeon sign create -g [group-id-goes-here]
This will initialize a signature in progress and return a Ceremony ID.
[!NOTE] You do not need a key share to initiate a signature proposal. This is an intentional design feature to allow CI/CD pipelines queue up a Signature Ceremony that clients can then opt into participating in.
By default, the final signature will be returned as a 128-character hex-encoded string (encoded as R || z).
You can pass an optional --openssh flag to return an OpenSSH-compatible signature.
freeon sign create --openssh -g [group-id-goes-here] file-with-message.txt
echo -n "MESSAGE TO BE SIGNED" | freeon sign create --openssh -g [group-id-goes-here]
You can run this command to flush any incomplete ceremonies.
freeon terminate [ceremony-id-goes-here]
[!WARNING] You do not need privileged access to perform this step.
Each client will need to run this command to participate in the ceremony.
freeon sign join -c [ceremony-id] file-with-message.txt
echo -n "MESSAGE TO BE SIGNED" | freeon sign join -c [ceremony-id]
# Identical:
freeon sign join --ceremony [ceremony-id] file-with-message.txt
echo -n "MESSAGE TO BE SIGNED" | freeon sign join --ceremony [ceremony-id]
You can furthermore pass the -i or --identity flag to specify the file path for your age secret keys.
freeon sign join -c [ceremony-id] -i /path/to/age.keys file-with-message.txt
echo -n "MESSAGE TO BE SIGNED" | freeon sign join -i /path/to/age.keys -c [ceremony-id]
# Identical
freeon sign join --ceremony [ceremony-id] --identity /path/to/age.keys file-with-message.txt
echo -n "MESSAGE TO BE SIGNED" | freeon sign join --identity /path/to/age.keys --ceremony [ceremony-id]
57 commits
Go
100.0%