The original plan for Safecat next release was grandiose. I wanted to set up a discussion forum for the United Web with zk-signup. It was too grandiose, so instead, we ended up with a modest release.
The release features a general solution for creating cryptographically signed certificates. Get the code here!
Here’s an example:
What’s new?
Without further ado:
-
A new cryptographically signed certificates mechanism. This is a very general solution. The certificate format is defined as a .toml file. Safecat comes with three existing formats, (
babyjubjub,babyjubjub-woolball, andevmaddress), but you can easily create your own formats since it’s just a matter of making a .toml file. -
Interactive certificates signing. This is done using the Inquire crate. The interactivity might be slow to some people, so we might add a faster, non-interactive, option (such as, reading certificate data from a file or entering all in one-line) in a future release.
-
Grumpty Cat. Wait wait, did I say the main new feature was something-something-certificates? I take it back! The main new feature is Grumpty Cat [sic].
-
When you type now ‘safecat –help’ you’ll be greeted, assuming that’s the right verb to use here, by a very grumpy, sarcastic cat patronizing you. We call it “Grumpty Cat” and it says each time a random sentence, and is drawn in ANSI.
Here are a few other less important changes.
- removed the ‘show-certs’ subcommand. There’s no sense to maintain it when things change so much at this stage.
- All math now uses the ark-ff crate.
- Code reorg, bug fixes, documentation improvements.
There are other projects creating similar certificates, notably, POD. But they are either not CLI or not written in Rust, and anyway have a different vision than Safecat.
What’s next?
Now that we can generate signed certificates easily, the next natural step is a prove system. As in, ‘safecat prove’ will generate proof that you have certificates backing up this claim.
Alas, this is not a trivial next step.
In order to prove claims about certificates, you need to get signed certificates. In the lack of people’s contacts directory and communication mechanism between Safecat users, it’s all done now via private messages. This is very inconvenient.
But then even if you have certificates, a claim might be true under one set of beliefs but false under another set. Like, if the persons you’re sending the proof to do not believe the integrity of the entities that signed your certificate, your proof means nothing to them.
These are two difficult problems to tackle. For the first one, we need some name system, but this clearly means inserting network communication with an outside server to Safecat, since any other solution is cumbersome to the point of failing. I tried. I can write a full article only about this.
For the second problem, we need a way for people to create, manage, and compare who they trust. This is almost equivalent to managing your Internet society, so yeah, also a daunting task.
Currently, I tend to approach the creation of transfer of certificates first. It’s a necessary step for anything else, and I also have already some experience in creating such things. But to avoid another four months of silence, what are the baby steps there? Not sure. Not sure.
Certificate Formats: A Technical Overview
Interested in creating your own certificate format? Let’s break down the process.
Below is an example of a certificate format (babyjubjub.toml):
[[to]]
fname = "WoolballName"
fdescription = "Who is the certificate for (Woolball#): "
ftype = "WoolballName"
[[to]]
fname = "BabyjubjubPubkey"
fdescription = "BabyjubjubPubkey (128 hex): "
ftype = "BabyjubjubPubkey"
[[body]]
fname = "Birthdate"
fdescription = "Date of birth"
ftype = "Timestamp"
[[body]]
fname = "Expiration"
fdescription = "Expiration Date"
ftype = "Timestamp"
A certificate is composed of two main sections: “to” and “body.” The “to” section identifies the recipient, which could be a single identifier (like a public key) or a set of identifiers. The “body” contains the certificate’s details.
Each field in the certificate has a name (“fname”), a description (“fdescription”), and a type (“ftype”). The type must be one of the values specified in the FieldTypeName enum. Currently, these types include:
enum FieldType {
Text(String),
Integer(u32),
Timestamp(DateTime<Utc>),
Age(u32),
BabyjubjubPubkey(babyjubjub::PubKey),
WoolballName(WoolballName),
EVMAddress(String),
}
To create a new certificate format, save it in the ‘data/certificate-formats’ directory. You can then generate a certificate based on your format by running ‘safecat attest [format-name]’. The certificate file should be named format-name.toml.
If no certificate name is provided, the default format used is ‘babyjubjub’. This format is minimalistic, with the identifier being a Baby Jubjub curve public key and the body containing only an expiration date. It’s ideal for basic use cases, such as issuing certificates of personhood.
How Are Certificates Signed?
Certificates aren’t signed as a single string, which would complicate verification in languages like Noir, which have limitations with string handling. Instead, Safecat follows this approach:
- Convert each certificate element into a BN254 field element, or a vector of such elements if needed.
- Represent the entire certificate as a vector of these field elements, starting with all “to” elements followed by the “body” elements.
- Sign this vector.
For more details, refer to the process in certificate.rs.

Comments
Nothing yet. Say the first thing.
Sign in to join the conversation.