Hash to curve algorithms for Rust

crate Docs Build Status dependency status Apache 2.0 Licensed Maintenance Status: Experimental Safety Dance

This repository implements various algorithms that can be used to encode or hash arbitrary input to a point on an elliptic curve or a set of recommended algorithms for a range of curve types.

Status

This crate is experimental and may have bugs/memory safety issues. USE AT YOUR OWN RISK!

Below is an outline of the of the suites supported by this crate:

Examples on using the code

To get started, you must define a DomainSeparationTag for your protocol use. According to section 3.1 in Current IETF Draft, domain separation tags must include a protocol id, and some other options like versioning, ciphersuites, and encoding names.

```rust use hash2curve::DomainSeparationTag

let dst = DomainSeparationTag::new(b"MySuperAwesomeProtocol", None, None, None).unwrap(); ```

DomainSeparationTag requires at least one 1 character otherwise new will throw an Err. This tag will then be used for creating a hash to curve struct. A good DomainSeparationTag according to the Current IETF Draft is protocol id = "BLS12381G1XMD:SHA-256SSWURO" which translates to mean hash on curve BLS12-381 to a point on G1 using the expandmessagexmd, the SHA-256 hash algorithm, the Simple SWU isogeny map, with a random oracle output (the output is indistinguishable from a random string). A protocol version might be 1.0, the ciphersuites could be "signatures", and "encoding" could be "base64". Only the protocol id is required.

Hashers are defined to create points on specific curves. All hashers define at least HashToCurveXmd or HashToCurveXof.

HashToCurveXmd is designed to use cryptographically secure hash functions like SHA-2 or SHA-3. HashToCurveXof is designed to use extensible output functions like SHAKE-128. Use the appropriate hasher struct for the curve used in your protocol.

Here is an example of creating BLS12-381 point using the hash to curve based on Apache Milagro

```rust use hash2curve::{DomainSeparationTag, HashToCurveXmd, bls381g1::Bls12381G1Sswu};

let dst = DomainSeparationTag::new(b"BLS12381G1XMD:SHA-256SSWURO", Some(b"0.1.0"), None, None).unwrap();

let hasher = Bls12381G1Sswu::new(dst);

let msg = b"A message to sign";

// sign the message assuming signatures are in G1 like tiny BLS let pointong1 = hasher.hashtocurvexmd::(msg); let signature = pointong1.mul(&privatekey);

// Or extract the bytes or save as hexstring let pointong1 = hasher.hashtocurvexmd::(msg).encodeto_hex(); ```

Tests

The tests can be execute by running: cargo test. However, since curves are very specific, no curve is enabled by default. Instead, the appropriate hasher struct can included using the following:

Current Features

Author

Michael Lodder

License

Licensed under either of * Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0) * MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be dual licensed as above, without any additional terms or conditions.

References