Skip to content

Commit

Permalink
Merge pull request #23 from cryptography-cafe/release-0.1
Browse files Browse the repository at this point in the history
Release 0.1.0
  • Loading branch information
str4d committed May 20, 2019
2 parents b73adb4 + 30d725b commit 548dce2
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 9 deletions.
46 changes: 45 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
# curve25519-elisabeth
# curve25519-elisabeth [![Maven Central](https://img.shields.io/maven-central/v/cafe.cryptography/curve25519-elisabeth.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22cafe.cryptography%22%20AND%20a:%22curve25519-elisabeth%22) [![Build Status](https://travis-ci.com/cryptography-cafe/curve25519-elisabeth.svg?branch=master)](https://travis-ci.com/cryptography-cafe/curve25519-elisabeth) [![Codecov](https://img.shields.io/codecov/c/gh/cryptography-cafe/curve25519-elisabeth.svg)](https://codecov.io/gh/cryptography-cafe/curve25519-elisabeth)

A pure-Java implementation of group operations on Curve25519.

Requires Java 7 or higher. Requires JDK 9 or higher to build.

# Usage

## Gradle

```
implementation 'cafe.cryptography:curve25519-elisabeth:0.1.0'
```

## Apache Maven

```
<dependency>
<groupId>cafe.cryptography</groupId>
<artifactId>curve25519-elisabeth</artifactId>
<version>0.1.0</version>
</dependency>
```

# Documentation

To view the public-facing API documentation, first build it:
Expand All @@ -23,6 +42,31 @@ The unstable internal implementation details are also documented. To build them:

Then open `build/docs/internal/index.html` in your browser.

# Safety

The `curve25519-elisabeth` types are designed to make illegal states unrepresentable.
For example, any instance of an `EdwardsPoint` is guaranteed to hold a point on the
Edwards curve, and any instance of a `RistrettoElement` is guaranteed to hold a valid
element in the Ristretto group.

These guarantees only hold if the internal implementation details of the types are opaque.
We use several techniques to achieve this in modern Java environments:

- For all classes that implement `java.io.Serializable`, the serialization APIs are
overridden to use the encoded form of the respective type, instead of directly
serializing the internal representation.

- For Java 9 and above, when this library is in the module path, reflection cannot be used
to access non-public classes or fields.

Usage of Java's reflection APIs on types from this library (in legacy environments or
configurations where it is possible to do so) is **NOT** supported.

All operations are implemented using constant-time logic (no secret-dependent branches, no
secret-dependent memory accesses), unless specifically marked as being variable-time code.
However, while our constant-time logic is lowered to constant-time JVM bytecode, we cannot
guarantee that the JVM will not figure out ways to optimise away constant-time logic.

# About

`curve25519-elisabeth` is authored by Jack Grigg.
Expand Down
39 changes: 38 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ tasks.jar {
}

group = "cafe.cryptography"
version = "0.0.0"
version = "0.1.0"

tasks.register<Jar>("sourcesJar") {
from(sourceSets.main.get().allJava)
Expand All @@ -72,6 +72,43 @@ publishing {
from(components["java"])
artifact(tasks["sourcesJar"])
artifact(tasks["javadocJar"])

pom {
name.set("curve25519-elisabeth")
description.set("Pure Java implementation of group operations on Curve25519")
url.set("https://cryptography.cafe")
licenses {
license {
name.set("MIT License")
url.set("https://opensource.org/licenses/MIT")
}
}
developers {
developer {
id.set("str4d")
name.set("Jack Grigg")
email.set("thestr4d@gmail.com")
}
}
scm {
connection.set("scm:git:git://github.com/cryptography-cafe/curve25519-elisabeth.git")
developerConnection.set("scm:git:ssh://github.com:cryptography-cafe/curve25519-elisabeth.git")
url.set("https://github.com/cryptography-cafe/curve25519-elisabeth/tree/master")
}
}
}
}
repositories {
maven {
val releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
val snapshotRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots/"
url = uri(if (version.toString().endsWith("SNAPSHOT")) snapshotRepoUrl else releasesRepoUrl)
credentials {
val NEXUS_USERNAME: String? by project
val NEXUS_PASSWORD: String? by project
username = NEXUS_USERNAME ?: ""
password = NEXUS_PASSWORD ?: ""
}
}
}
}
Expand Down
14 changes: 7 additions & 7 deletions src/main/java/cafe/cryptography/curve25519/RistrettoElement.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,13 @@ static RistrettoElement map(final FieldElement t) {
* @return the resulting element.
*/
public static RistrettoElement fromUniformBytes(final byte[] b) {
// 1. Interpret the low 255 bits of b[ 0..32] as an integer r0 in
// little-endian representation. Reduce r0 modulo p.
// 1. Interpret the least significant 255 bits of b[ 0..32] as an
// integer r0 in little-endian representation. Reduce r0 modulo p.
final byte[] b0 = Arrays.copyOfRange(b, 0, 32);
final FieldElement r0 = FieldElement.fromByteArray(b0);

// 2. Interpret the low 255 bits of b[32..64] as an integer r1 in
// little-endian representation. Reduce r1 modulo p.
// 2. Interpret the least significant 255 bits of b[32..64] as an
// integer r1 in little-endian representation. Reduce r1 modulo p.
final byte[] b1 = Arrays.copyOfRange(b, 32, 64);
final FieldElement r1 = FieldElement.fromByteArray(b1);

Expand Down Expand Up @@ -205,9 +205,9 @@ public boolean equals(Object obj) {
public int hashCode() {
// The general contract for the hashCode method states that equal objects must
// have equal hash codes. Object equality is based on the encodings of the
// elements, not their internal representations (are not canonical). Note that
// equality is actually implemented using the ristretto255 EQUALS function, but
// it is simpler to derive a hashCode from the element's encoding.
// elements, not their internal representations (which are not canonical). Note
// that equality is actually implemented using the ristretto255 EQUALS function,
// but it is simpler to derive a hashCode from the element's encoding.
return compress().hashCode();
}

Expand Down

0 comments on commit 548dce2

Please sign in to comment.