1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
go-ristretto
============
Many cryptographic schemes need a group of prime order. Popular and
efficient elliptic curves like (Edwards25519 of `ed25519` fame) are
rarely of prime order. There is, however, a convenient method
to construct a prime order group from such curves,
called [Ristretto](https://ristretto.group) proposed by
[Mike Hamburg](https://www.shiftleft.org).
This is a pure Go implementation of the group operations on the
Ristretto prime-order group built from Edwards25519.
Documentation is on [godoc](https://godoc.org/github.com/bwesterb/go-ristretto).
Example: El'Gamal encryption
----------------------------
```go
// Generate an El'Gamal keypair
var secretKey ristretto.Scalar
var publicKey ristretto.Point
secretKey.Rand() // generate a new secret key
publicKey.ScalarMultBase(&secretKey) // compute public key
// El'Gamal encrypt a random curve point p into a ciphertext-pair (c1,c2)
var p ristretto.Point
var r ristretto.Scalar
var c1 ristretto.Point
var c2 ristretto.Point
p.Rand()
r.Rand()
c2.ScalarMultBase(&r)
c1.PublicScalarMult(&publicKey, &r)
c1.Add(&c1, &p)
// Decrypt (c1,c2) back to p
var blinding, p2 ristretto.Point
blinding.ScalarMult(&c2, &secretKey)
p2.Sub(&c1, &blinding)
fmt.Printf("%v", bytes.Equal(p.Bytes(), p2.Bytes()))
// Output:
// true
```
Compatibility with `ristretto255` RFC draft
-------------------------------------------
An [RFC has been proposed](https://datatracker.ietf.org/doc/draft-hdevalence-cfrg-ristretto/)
to standardise Ristretto over Ed25519. This RFC is compatible with `go-ristretto`. There
is one caveat: one should use `Point.DeriveDalek` instead of `Point.Derive` to derive a point
from a string.
References
----------
The curve and Ristretto implementation is based on the unpublished
[PandA](https://link.springer.com/chapter/10.1007/978-3-319-04873-4_14)
library by
[Chuengsatiansup](https://perso.ens-lyon.fr/chitchanok.chuengsatiansup/),
[Ribarski](http://panceribarski.com) and
[Schwabe](https://cryptojedi.org/peter/index.shtml),
see [cref/cref.c](cref/cref.c). The old generic radix 25.5 field operations borrow
from [Adam Langley](https://www.imperialviolet.org)'s
[ed25519](http://github.com/agl/ed25519).
The amd64 optimized field arithmetic are from George Tankersley's
[ed25519 patch](https://go-review.googlesource.com/c/crypto/+/71950),
which in turn is based on SUPERCOP's
[`amd64-51-30k`](https://github.com/floodyberry/supercop/tree/master/crypto_sign/ed25519/amd64-51-30k)
by Bernstein, Duif, Lange, Schwabe and Yang.
The new generic radix 51 field operations are also based on `amd64-51-30k`.
The variable-time scalar multiplication code is based on that
of [curve25519-dalek](https://github.com/dalek-cryptography/curve25519-dalek).
The Lizard encoding was proposed by [Bram Westerbaan](https://bram.westerbaan.name/).
The quick RistrettoElligator inversion for it is joint work
with [Bram Westerbaan](https://bram.westerbaan.name/)
and [Mike Hamburg](https://www.shiftleft.org).
### other platforms
* [Rust](https://github.com/dalek-cryptography/curve25519-dalek)
* [Javascript](https://github.com/jedisct1/wasm-crypto)
* [C (part of `libsodium`)](https://libsodium.gitbook.io/doc/advanced/point-arithmetic/ristretto)
Changes
-------
### 1.2.3 (16-03-2023)
- Panic when reading randomness fails.
### 1.2.2 (29-07-2022)
- Add Point.ConditionalSet() and Scalar.ConditionalSet().
### 1.2.1 (08-11-2021)
- Add Scalar.SetUint64().
### 1.2.0 (17-02-2021)
- Add Point.Double(). See issue #21.
- To align more closely with the RFC, Point.SetBytes()
and Point.UnmarshalBinary() will now reject points with non-canonical
encodings. See #20.
### 1.1.1 (24-09-2019)
- Only use bits.Add64 from Go 1.13 onwards to make sure we're constant-time
on non-amd64 platforms. Thanks @Yawning; see issue #17.
### 1.1.0 (13-05-2019)
- Add support for the Lizard 16-bytes-to-point-injection.
See `ristretto.Point.`{`SetLizard()`, `Lizard()`,`LizardInto()`}.
- Add `Scalar.DeriveShort()` to derive a half-length scalar.
(Warning: half-length scalars are unsafe in almost every application.)
- (internal) Add `ExtendedPoint.RistrettoElligator2Inverse()` to compute
all preimages of a given point up-to Ristretto equivalence
of `CompletedPoint.SetRistrettoElligator2()`.
|