pax_global_header00006660000000000000000000000064151456725410014524gustar00rootroot0000000000000052 comment=495bacc79ec5a4bc2aeaa7793d15dbb434b4938a golang-github-gtank-ristretto255-0.2.0/000077500000000000000000000000001514567254100176455ustar00rootroot00000000000000golang-github-gtank-ristretto255-0.2.0/LICENSE000066400000000000000000000030741514567254100206560ustar00rootroot00000000000000Copyright (c) 2009 The Go Authors. All rights reserved. Copyright (c) 2017 George Tankersley. All rights reserved. Copyright (c) 2019 Henry de Valence. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. golang-github-gtank-ristretto255-0.2.0/README.md000066400000000000000000000006041514567254100211240ustar00rootroot00000000000000# ristretto255 [![GoDoc](https://godoc.org/github.com/gtank/ristretto255?status.svg)](https://godoc.org/github.com/gtank/ristretto255) Package ristretto255 implements the group operations from [RFC 9496, Section 4.3](https://datatracker.ietf.org/doc/html/rfc9496#section-4.3) and the scalar field from [RFC 9496, Section 4.4](https://datatracker.ietf.org/doc/html/rfc9496#section-4.4). golang-github-gtank-ristretto255-0.2.0/go.mod000066400000000000000000000001261514567254100207520ustar00rootroot00000000000000module github.com/gtank/ristretto255 go 1.23 require filippo.io/edwards25519 v1.1.0 golang-github-gtank-ristretto255-0.2.0/go.sum000066400000000000000000000002451514567254100210010ustar00rootroot00000000000000filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= golang-github-gtank-ristretto255-0.2.0/ristretto255.go000066400000000000000000000350211514567254100224700ustar00rootroot00000000000000// Copyright 2019 The Go Authors. All rights reserved. // Copyright 2019 George Tankersley. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Package ristretto255 implements the group of prime order // // 2**252 + 27742317777372353535851937790883648493 // // and its scalar field, as specified in RFC 9496, Section 4. // // All operations are constant time unless otherwise specified. package ristretto255 import ( "bytes" "encoding/base64" "errors" "filippo.io/edwards25519" "filippo.io/edwards25519/field" ) // Constants from RFC 9496, Section 4.1. // See TestConstants for their decimal values. var ( d, _ = new(field.Element).SetBytes([]byte{ 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75, 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00, 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c, 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52, }) sqrtM1, _ = new(field.Element).SetBytes([]byte{ 0xb0, 0xa0, 0x0e, 0x4a, 0x27, 0x1b, 0xee, 0xc4, 0x78, 0xe4, 0x2f, 0xad, 0x06, 0x18, 0x43, 0x2f, 0xa7, 0xd7, 0xfb, 0x3d, 0x99, 0x00, 0x4d, 0x2b, 0x0b, 0xdf, 0xc1, 0x4f, 0x80, 0x24, 0x83, 0x2b, }) sqrtADMinusOne, _ = new(field.Element).SetBytes([]byte{ 0x1b, 0x2e, 0x7b, 0x49, 0xa0, 0xf6, 0x97, 0x7e, 0xbd, 0x54, 0x78, 0x1b, 0x0c, 0x8e, 0x9d, 0xaf, 0xfd, 0xd1, 0xf5, 0x31, 0xc9, 0xfc, 0x3c, 0x0f, 0xac, 0x48, 0x83, 0x2b, 0xbf, 0x31, 0x69, 0x37, }) invSqrtAMinusD, _ = new(field.Element).SetBytes([]byte{ 0xea, 0x40, 0x5d, 0x80, 0xaa, 0xfd, 0xc8, 0x99, 0xbe, 0x72, 0x41, 0x5a, 0x17, 0x16, 0x2f, 0x9d, 0x40, 0xd8, 0x01, 0xfe, 0x91, 0x7b, 0xc2, 0x16, 0xa2, 0xfc, 0xaf, 0xcf, 0x05, 0x89, 0x6c, 0x78, }) oneMinusDSQ, _ = new(field.Element).SetBytes([]byte{ 0x76, 0xc1, 0x5f, 0x94, 0xc1, 0x09, 0x7c, 0xe2, 0x0f, 0x35, 0x5e, 0xcd, 0x38, 0xa1, 0x81, 0x2c, 0xe4, 0xdf, 0x70, 0xbe, 0xdd, 0xab, 0x94, 0x99, 0xd7, 0xe0, 0xb3, 0xb2, 0xa8, 0x72, 0x90, 0x02, }) dMinusOneSQ, _ = new(field.Element).SetBytes([]byte{ 0x20, 0x4d, 0xed, 0x44, 0xaa, 0x5a, 0xad, 0x31, 0x99, 0x19, 0x1e, 0xb0, 0x2c, 0x4a, 0x9e, 0xd2, 0xeb, 0x4e, 0x9b, 0x52, 0x2f, 0xd3, 0xdc, 0x4c, 0x41, 0x22, 0x6c, 0xf6, 0x7a, 0xb3, 0x68, 0x59, }) ) var ( zero = new(field.Element) one = new(field.Element).One() two = new(field.Element).Add(one, one) minusOne = new(field.Element).Subtract(zero, one) ) // Element is an element of the ristretto255 prime-order group. type Element struct { r edwards25519.Point } // NewElement returns a new Element set to the identity value. // // Deprecated: use NewIdentityElement. This API will be removed before v1.0.0. func NewElement() *Element { return NewIdentityElement() } // NewIdentityElement returns a new Element set to the identity value. func NewIdentityElement() *Element { e := &Element{} e.r.Set(edwards25519.NewIdentityPoint()) return e } // NewGeneratorElement returns a new Element set to the canonical generator. func NewGeneratorElement() *Element { e := &Element{} e.r.Set(edwards25519.NewGeneratorPoint()) return e } // Set sets the value of e to x and returns e. func (e *Element) Set(x *Element) *Element { *e = *x return e } // Equal returns 1 if e is equivalent to ee, and 0 otherwise. // // Equal implements the Equals operation from RFC 9496, Section 4.3.3. func (e *Element) Equal(ee *Element) int { X1, Y1, _, _ := e.r.ExtendedCoordinates() X2, Y2, _, _ := ee.r.ExtendedCoordinates() var f0, f1 field.Element f0.Multiply(X1, Y2) // x1 * y2 f1.Multiply(Y1, X2) // y1 * x2 out := f0.Equal(&f1) f0.Multiply(Y1, Y2) // y1 * y2 f1.Multiply(X1, X2) // x1 * x2 out = out | f0.Equal(&f1) return out } // FromUniformBytes maps the 64-byte slice b to e uniformly and // deterministically, and returns e. This can be used for hash-to-group // operations or to obtain a random element. // // Deprecated: use SetUniformBytes. This API will be removed before v1.0.0. func (e *Element) FromUniformBytes(b []byte) *Element { if _, err := e.SetUniformBytes(b); err != nil { panic(err.Error()) } return e } // SetUniformBytes deterministically sets e to a uniformly distributed value // given 64 uniformly distributed random bytes. // // This can be used for hash-to-group operations or to obtain a random element. // // SetUniformBytes implements the Element Derivation operation from RFC 9496, // Section 4.3.4. func (e *Element) SetUniformBytes(b []byte) (*Element, error) { if len(b) != 64 { return nil, errors.New("ristretto255: SetUniformBytes input is not 64 bytes long") } f := &field.Element{} f.SetBytes(b[:32]) point1 := &Element{} mapToPoint(&point1.r, f) f.SetBytes(b[32:]) point2 := &Element{} mapToPoint(&point2.r, f) return e.Add(point1, point2), nil } // mapToPoint implements MAP from Section 3.2.4 of draft-hdevalence-cfrg-ristretto-00. func mapToPoint(out *edwards25519.Point, t *field.Element) { // r = SQRT_M1 * t^2 r := &field.Element{} r.Multiply(sqrtM1, r.Square(t)) // u = (r + 1) * ONE_MINUS_D_SQ u := &field.Element{} u.Multiply(u.Add(r, one), oneMinusDSQ) // c = -1 c := &field.Element{} c.Set(minusOne) // v = (c - r*D) * (r + D) rPlusD := &field.Element{} rPlusD.Add(r, d) v := &field.Element{} v.Multiply(v.Subtract(c, v.Multiply(r, d)), rPlusD) // (was_square, s) = SQRT_RATIO_M1(u, v) s := &field.Element{} _, wasSquare := s.SqrtRatio(u, v) // s_prime = -CT_ABS(s*t) sPrime := &field.Element{} sPrime.Negate(sPrime.Absolute(sPrime.Multiply(s, t))) // s = CT_SELECT(s IF was_square ELSE s_prime) s.Select(s, sPrime, wasSquare) // c = CT_SELECT(c IF was_square ELSE r) c.Select(c, r, wasSquare) // N = c * (r - 1) * D_MINUS_ONE_SQ - v N := &field.Element{} N.Multiply(c, N.Subtract(r, one)) N.Subtract(N.Multiply(N, dMinusOneSQ), v) s2 := &field.Element{} s2.Square(s) // w0 = 2 * s * v w0 := &field.Element{} w0.Add(w0, w0.Multiply(s, v)) // w1 = N * SQRT_AD_MINUS_ONE w1 := &field.Element{} w1.Multiply(N, sqrtADMinusOne) // w2 = 1 - s^2 w2 := &field.Element{} w2.Subtract(one, s2) // w3 = 1 + s^2 w3 := &field.Element{} w3.Add(one, s2) // return (w0*w3, w2*w1, w1*w3, w0*w2) var X, Y, Z, T field.Element X.Multiply(w0, w3) Y.Multiply(w2, w1) Z.Multiply(w1, w3) T.Multiply(w0, w2) if _, err := out.SetExtendedCoordinates(&X, &Y, &Z, &T); err != nil { panic("ristretto255: internal error: MAP generated invalid coordinates") } } // Encode appends the 32 bytes canonical encoding of e to b // and returns the result. // // Deprecated: use Bytes. This API will be removed before v1.0.0. func (e *Element) Encode(b []byte) []byte { ret, out := sliceForAppend(b, 32) e.bytes(out) return ret } // sliceForAppend takes a slice and a requested number of bytes. It returns a // slice with the contents of the given slice followed by that many bytes and a // second slice that aliases into it and contains only the extra bytes. If the // original slice has sufficient capacity then no allocation is performed. func sliceForAppend(in []byte, n int) (head, tail []byte) { if total := len(in) + n; cap(in) >= total { head = in[:total] } else { head = make([]byte, total) copy(head, in) } tail = head[len(in):] return } // Bytes returns the 32 bytes canonical encoding of e. // // Bytes implements the Encode operation from RFC 9496, Section 4.3.2. func (e *Element) Bytes() []byte { // Bytes is outlined to let the allocation happen on the stack of the caller. b := make([]byte, 32) return e.bytes(b) } func (e *Element) bytes(b []byte) []byte { X, Y, Z, T := e.r.ExtendedCoordinates() tmp := &field.Element{} // u1 = (z0 + y0) * (z0 - y0) u1 := &field.Element{} u1.Add(Z, Y).Multiply(u1, tmp.Subtract(Z, Y)) // u2 = x0 * y0 u2 := &field.Element{} u2.Multiply(X, Y) // Ignore was_square since this is always square // (_, invsqrt) = SQRT_RATIO_M1(1, u1 * u2^2) invSqrt := &field.Element{} invSqrt.SqrtRatio(one, tmp.Square(u2).Multiply(tmp, u1)) // den1 = invsqrt * u1 // den2 = invsqrt * u2 den1, den2 := &field.Element{}, &field.Element{} den1.Multiply(invSqrt, u1) den2.Multiply(invSqrt, u2) // z_inv = den1 * den2 * t0 zInv := &field.Element{} zInv.Multiply(den1, den2).Multiply(zInv, T) // ix0 = x0 * SQRT_M1 // iy0 = y0 * SQRT_M1 ix0, iy0 := &field.Element{}, &field.Element{} ix0.Multiply(X, sqrtM1) iy0.Multiply(Y, sqrtM1) // enchanted_denominator = den1 * INVSQRT_A_MINUS_D enchantedDenominator := &field.Element{} enchantedDenominator.Multiply(den1, invSqrtAMinusD) // rotate = IS_NEGATIVE(t0 * z_inv) rotate := tmp.Multiply(T, zInv).IsNegative() // x = CT_SELECT(iy0 IF rotate ELSE x0) // y = CT_SELECT(ix0 IF rotate ELSE y0) x, y := &field.Element{}, &field.Element{} x.Select(iy0, X, rotate) y.Select(ix0, Y, rotate) // z = z0 z := Z // den_inv = CT_SELECT(enchanted_denominator IF rotate ELSE den2) denInv := &field.Element{} denInv.Select(enchantedDenominator, den2, rotate) // y = CT_NEG(y, IS_NEGATIVE(x * z_inv)) isNegative := tmp.Multiply(x, zInv).IsNegative() y.Select(tmp.Negate(y), y, isNegative) // s = CT_ABS(den_inv * (z - y)) s := tmp.Subtract(z, y).Multiply(tmp, denInv).Absolute(tmp) // Return the canonical little-endian encoding of s. copy(b, s.Bytes()) return b } var errInvalidEncoding = errors.New("ristretto255: invalid element encoding") // Decode sets e to the decoded value of in. If in is not a 32 byte canonical // encoding, Decode returns an error, and the receiver is unchanged. // // Deprecated: use SetCanonicalBytes. This API will be removed before v1.0.0. func (e *Element) Decode(in []byte) error { _, err := e.SetCanonicalBytes(in) return err } // SetCanonicalBytes sets e to the decoded value of in. If in is not a canonical // encoding of s, SetCanonicalBytes returns nil and an error and the receiver is // unchanged. // // SetCanonicalBytes implements the Decode operation from RFC 9496, Section 4.3.1. func (e *Element) SetCanonicalBytes(in []byte) (*Element, error) { if len(in) != 32 { return nil, errInvalidEncoding } // First, interpret the string as an integer s in little-endian representation. s := &field.Element{} s.SetBytes(in) // If the resulting value is >= p, decoding fails. if !bytes.Equal(s.Bytes(), in) { return nil, errInvalidEncoding } // If IS_NEGATIVE(s) returns TRUE, decoding fails. if s.IsNegative() == 1 { return nil, errInvalidEncoding } // ss = s^2 sSqr := &field.Element{} sSqr.Square(s) // u1 = 1 - ss u1 := &field.Element{} u1.Subtract(one, sSqr) // u2 = 1 + ss u2 := &field.Element{} u2.Add(one, sSqr) // u2_sqr = u2^2 u2Sqr := &field.Element{} u2Sqr.Square(u2) // v = -(D * u1^2) - u2_sqr v := &field.Element{} v.Square(u1).Multiply(v, d).Negate(v).Subtract(v, u2Sqr) // (was_square, invsqrt) = SQRT_RATIO_M1(1, v * u2_sqr) invSqrt, tmp := &field.Element{}, &field.Element{} _, wasSquare := invSqrt.SqrtRatio(one, tmp.Multiply(v, u2Sqr)) // den_x = invsqrt * u2 // den_y = invsqrt * den_x * v denX, denY := &field.Element{}, &field.Element{} denX.Multiply(invSqrt, u2) denY.Multiply(invSqrt, denX).Multiply(denY, v) // x = CT_ABS(2 * s * den_x) // y = u1 * den_y // t = x * y var X, Y, Z, T field.Element X.Multiply(two, s).Multiply(&X, denX).Absolute(&X) Y.Multiply(u1, denY) Z.One() T.Multiply(&X, &Y) // If was_square is FALSE, or IS_NEGATIVE(t) returns TRUE, or y = 0, decoding fails. if wasSquare == 0 || T.IsNegative() == 1 || Y.Equal(zero) == 1 { return nil, errInvalidEncoding } // Otherwise, return the internal representation in extended coordinates (x, y, 1, t). if _, err := e.r.SetExtendedCoordinates(&X, &Y, &Z, &T); err != nil { panic("ristretto255: internal error: DECODE generated invalid coordinates") } return e, nil } // ScalarBaseMult sets e = s * B, where B is the canonical generator, and returns e. func (e *Element) ScalarBaseMult(s *Scalar) *Element { e.r.ScalarBaseMult(&s.s) return e } // ScalarMult sets e = s * p, and returns e. func (e *Element) ScalarMult(s *Scalar, p *Element) *Element { e.r.ScalarMult(&s.s, &p.r) return e } // MultiScalarMult sets e = sum(s[i] * p[i]), and returns e. // // Execution time depends only on the lengths of the two slices, which must match. func (e *Element) MultiScalarMult(s []*Scalar, p []*Element) *Element { if len(p) != len(s) { panic("ristretto255: MultiScalarMult invoked with mismatched slice lengths") } points := make([]*edwards25519.Point, len(p)) scalars := make([]*edwards25519.Scalar, len(s)) for i := range s { points[i] = &p[i].r scalars[i] = &s[i].s } e.r.MultiScalarMult(scalars, points) return e } // VarTimeMultiScalarMult sets e = sum(s[i] * p[i]), and returns e. // // Execution time depends on the inputs. func (e *Element) VarTimeMultiScalarMult(s []*Scalar, p []*Element) *Element { if len(p) != len(s) { panic("ristretto255: VarTimeMultiScalarMult invoked with mismatched slice lengths") } points := make([]*edwards25519.Point, len(p)) scalars := make([]*edwards25519.Scalar, len(s)) for i := range s { points[i] = &p[i].r scalars[i] = &s[i].s } e.r.VarTimeMultiScalarMult(scalars, points) return e } // VarTimeDoubleScalarBaseMult sets e = a * A + b * B, where B is the canonical // generator, and returns e. // // Execution time depends on the inputs. func (e *Element) VarTimeDoubleScalarBaseMult(a *Scalar, A *Element, b *Scalar) *Element { e.r.VarTimeDoubleScalarBaseMult(&a.s, &A.r, &b.s) return e } // Add sets e = p + q, and returns e. func (e *Element) Add(p, q *Element) *Element { e.r.Add(&p.r, &q.r) return e } // Subtract sets e = p - q, and returns e. func (e *Element) Subtract(p, q *Element) *Element { e.r.Subtract(&p.r, &q.r) return e } // Negate sets e = -p, and returns e. func (e *Element) Negate(p *Element) *Element { e.r.Negate(&p.r) return e } // Zero sets e to the identity element of the group, and returns e. // // Deprecated: use NewIdentityElement and Set. This API will be removed before v1.0.0. func (e *Element) Zero() *Element { return e.Set(NewIdentityElement()) } // Base sets e to the canonical generator, and returns e. // // Deprecated: use NewGeneratorElement and Set. This API will be removed before v1.0.0. func (e *Element) Base() *Element { return e.Set(NewGeneratorElement()) } // MarshalText implements encoding/TextMarshaler interface func (e *Element) MarshalText() (text []byte, err error) { b := e.Encode([]byte{}) return []byte(base64.StdEncoding.EncodeToString(b)), nil } // UnmarshalText implements encoding/TextMarshaler interface func (e *Element) UnmarshalText(text []byte) error { eb, err := base64.StdEncoding.DecodeString(string(text)) if err == nil { return e.Decode(eb) } return err } // String implements the Stringer interface func (e *Element) String() string { result, _ := e.MarshalText() return string(result) } golang-github-gtank-ristretto255-0.2.0/ristretto255_test.go000066400000000000000000000277301514567254100235370ustar00rootroot00000000000000package ristretto255 import ( "bytes" "crypto/sha512" "encoding/hex" "encoding/json" "math/big" "testing" "filippo.io/edwards25519/field" ) // The encoding of the canonical generator. var compressedRistrettoBasepoint, _ = hex.DecodeString("e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76") func TestRistrettoBasepointRoundTrip(t *testing.T) { decodedBasepoint := &Element{} err := decodedBasepoint.Decode(compressedRistrettoBasepoint) if err != nil { t.Fatal(err) } ristrettoBasepoint := (&Element{}).Base() if decodedBasepoint.Equal(ristrettoBasepoint) != 1 { t.Error("decode succeeded, but got wrong point") } roundtripBasepoint := decodedBasepoint.Encode(nil) if !bytes.Equal(compressedRistrettoBasepoint, roundtripBasepoint) { t.Error("decode<>encode roundtrip produced different results") } encodedBasepoint := ristrettoBasepoint.Encode(nil) if !bytes.Equal(compressedRistrettoBasepoint, encodedBasepoint) { t.Error("point encode produced different results") } } func TestRistrettoSmallMultiplesTestVectors(t *testing.T) { // From RFC 9496, Appendix A.1. var testVectors = [16]string{ // This is the identity point "0000000000000000000000000000000000000000000000000000000000000000", // This is the basepoint "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76", // These are small multiples of the basepoint "6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919", "94741f5d5d52755ece4f23f044ee27d5d1ea1e2bd196b462166b16152a9d0259", "da80862773358b466ffadfe0b3293ab3d9fd53c5ea6c955358f568322daf6a57", "e882b131016b52c1d3337080187cf768423efccbb517bb495ab812c4160ff44e", "f64746d3c92b13050ed8d80236a7f0007c3b3f962f5ba793d19a601ebb1df403", "44f53520926ec81fbd5a387845beb7df85a96a24ece18738bdcfa6a7822a176d", "903293d8f2287ebe10e2374dc1a53e0bc887e592699f02d077d5263cdd55601c", "02622ace8f7303a31cafc63f8fc48fdc16e1c8c8d234b2f0d6685282a9076031", "20706fd788b2720a1ed2a5dad4952b01f413bcf0e7564de8cdc816689e2db95f", "bce83f8ba5dd2fa572864c24ba1810f9522bc6004afe95877ac73241cafdab42", "e4549ee16b9aa03099ca208c67adafcafa4c3f3e4e5303de6026e3ca8ff84460", "aa52e000df2e16f55fb1032fc33bc42742dad6bd5a8fc0be0167436c5948501f", "46376b80f409b29dc2b5f6f0c52591990896e5716f41477cd30085ab7f10301e", "e0c418f7c8d9c4cdd7395b93ea124f3ad99021bb681dfc3302a9d99a2e53e64e", } basepointMultiple := (&Element{}).Zero() ristrettoBasepoint := (&Element{}).Base() for i := range testVectors { // Grab the bytes of the encoding encoding, err := hex.DecodeString(testVectors[i]) if err != nil { t.Fatalf("#%d: bad hex encoding in test vector: %v", i, err) } // Decode the test vector to a ristretto255 element decodedPoint := Element{} err = decodedPoint.Decode(encoding) if err != nil { t.Fatalf("#%d: could not decode test vector: %v", i, err) } // Re-encode and check round trips roundtripEncoding := decodedPoint.Encode(nil) if !bytes.Equal(encoding, roundtripEncoding) { t.Errorf("#%d: decode<>encode roundtrip failed", i) } // Check that the test vector encodes i * B if basepointMultiple.Equal(&decodedPoint) != 1 { t.Errorf("decoded small multiple %d * B is not %d * B", i, i) } computedEncoding := basepointMultiple.Encode(nil) if !bytes.Equal(encoding, computedEncoding) { t.Errorf("#%d: encoding computed value did not match", i) } // Ensure basepointMultiple = i * B in the next iteration basepointMultiple.Add(basepointMultiple, ristrettoBasepoint) } } func TestRistrettoBadEncodingsTestVectors(t *testing.T) { // From RFC 9496, Appendix A.2. var testVectors = []string{ // These are all bad because they're non-canonical field encodings. "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", "f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", // These are all bad because they're negative field elements. "0100000000000000000000000000000000000000000000000000000000000000", "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", "ed57ffd8c914fb201471d1c3d245ce3c746fcbe63a3679d51b6a516ebebe0e20", "c34c4e1826e5d403b78e246e88aa051c36ccf0aafebffe137d148a2bf9104562", "c940e5a4404157cfb1628b108db051a8d439e1a421394ec4ebccb9ec92a8ac78", "47cfc5497c53dc8e61c91d17fd626ffb1c49e2bca94eed052281b510b1117a24", "f1c6165d33367351b0da8f6e4511010c68174a03b6581212c71c0e1d026c3c72", "87260f7a2f12495118360f02c26a470f450dadf34a413d21042b43b9d93e1309", // These are all bad because they give a nonsquare x^2. "26948d35ca62e643e26a83177332e6b6afeb9d08e4268b650f1f5bbd8d81d371", "4eac077a713c57b4f4397629a4145982c661f48044dd3f96427d40b147d9742f", "de6a7b00deadc788eb6b6c8d20c0ae96c2f2019078fa604fee5b87d6e989ad7b", "bcab477be20861e01e4a0e295284146a510150d9817763caf1a6f4b422d67042", "2a292df7e32cababbd9de088d1d1abec9fc0440f637ed2fba145094dc14bea08", "f4a9e534fc0d216c44b218fa0c42d99635a0127ee2e53c712f70609649fdff22", "8268436f8c4126196cf64b3c7ddbda90746a378625f9813dd9b8457077256731", "2810e5cbc2cc4d4eece54f61c6f69758e289aa7ab440b3cbeaa21995c2f4232b", // These are all bad because they give a negative xy value. "3eb858e78f5a7254d8c9731174a94f76755fd3941c0ac93735c07ba14579630e", "a45fdc55c76448c049a1ab33f17023edfb2be3581e9c7aade8a6125215e04220", "d483fe813c6ba647ebbfd3ec41adca1c6130c2beeee9d9bf065c8d151c5f396e", "8a2e1d30050198c65a54483123960ccc38aef6848e1ec8f5f780e8523769ba32", "32888462f8b486c68ad7dd9610be5192bbeaf3b443951ac1a8118419d9fa097b", "227142501b9d4355ccba290404bde41575b037693cef1f438c47f8fbf35d1165", "5c37cc491da847cfeb9281d407efc41e15144c876e0170b499a96a22ed31e01e", "445425117cb8c90edcbc7c1cc0e74f747f2c1efa5630a967c64f287792a48a4b", // This is s = -1, which causes y = 0. "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", } basepointMultiple := Element{} basepointMultiple.Zero() for i := range testVectors { // Grab the bytes of the encoding encoding, err := hex.DecodeString(testVectors[i]) if err != nil { t.Fatalf("#%d: bad hex encoding in test vector: %v", i, err) } // Attempt decoding decodedPoint := Element{} err = decodedPoint.Decode(encoding) if err == nil { t.Fatalf("#%d: did not fail on bad encoding", i) } } } func TestRistrettoFromUniformBytesTestVectors(t *testing.T) { // From RFC 9496, Appendix A.3, except the RFC published the SHA-512 images. inputs := []string{ "Ristretto is traditionally a short shot of espresso coffee", "made with the normal amount of ground coffee but extracted with", "about half the amount of water in the same amount of time", "by using a finer grind.", "This produces a concentrated shot of coffee per volume.", "Just pulling a normal shot short will produce a weaker shot", "and is not a Ristretto as some believe.", } elements := []string{ "3066f82a1a747d45120d1740f14358531a8f04bbffe6a819f86dfe50f44a0a46", "f26e5b6f7d362d2d2a94c5d0e7602cb4773c95a2e5c31a64f133189fa76ed61b", "006ccd2a9e6867e6a2c5cea83d3302cc9de128dd2a9a57dd8ee7b9d7ffe02826", "f8f0c87cf237953c5890aec3998169005dae3eca1fbb04548c635953c817f92a", "ae81e7dedf20a497e10c304a765c1767a42d6e06029758d2d7e8ef7cc4c41179", "e2705652ff9f5e44d3e841bf1c251cf7dddb77d140870d1ab2ed64f1a9ce8628", "80bd07262511cdde4863f8a7434cef696750681cb9510eea557088f76d9e5065", } var element Element for i, input := range inputs { hash := sha512.Sum512([]byte(input)) element.FromUniformBytes(hash[:]) if encoding := hex.EncodeToString(element.Encode(nil)); encoding != elements[i] { t.Errorf("#%d: expected %q, got %q", i, elements[i], encoding) } } } func TestEquivalentFromUniformBytes(t *testing.T) { // From RFC 9496, Appendix A.3. inputs := []string{ "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "1200000000000000000000000000000000000000000000000000000000000000", "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0000000000000000000000000000000000000000000000000000000000000080" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", "0000000000000000000000000000000000000000000000000000000000000000" + "1200000000000000000000000000000000000000000000000000000000000080", } expected := "304282791023b73128d277bdcb5c7746ef2eac08dde9f2983379cb8e5ef0517f" var element Element for i, input := range inputs { h, err := hex.DecodeString(input) if err != nil { t.Fatalf("#%d: bad hex encoding in test vector: %v", i, err) } element.FromUniformBytes(h[:]) if encoding := hex.EncodeToString(element.Encode(nil)); encoding != expected { t.Errorf("#%d: expected %q, got %q", i, expected, encoding) } } } func TestMarshalScalar(t *testing.T) { x := new(Scalar) // generate an arbitrary scalar xbytes := sha512.Sum512([]byte("Hello World")) x.SetUniformBytes(xbytes[:]) text, err := json.Marshal(x) if err != nil { t.Fatalf("Could not marshal json: %v", err) } t.Logf("json: %s", text) y := new(Scalar) err = json.Unmarshal(text, y) if err != nil || y.Equal(x) == 0 { t.Fatalf("Error unmarshaling scalar from json: %s %v", text, err) } } func TestMarshalElement(t *testing.T) { x := new(Element) // generate an arbitrary element xbytes := sha512.Sum512([]byte("Hello World")) x.FromUniformBytes(xbytes[:]) text, err := json.Marshal(x) if err != nil { t.Fatalf("Could not marshal json: %v", err) } t.Logf("json: %s", text) y := new(Element) err = json.Unmarshal(text, y) if err != nil || y.Equal(x) == 0 { t.Fatalf("Error unmarshaling element from json: %s %v", text, err) } } func TestElementSet(t *testing.T) { // Test this, because the internal point type being hard-copyable isn't part of the spec. el1 := NewIdentityElement() el2 := NewGeneratorElement() if el1.Equal(el2) == 1 { t.Error("shouldn't be the same") } // Check new value el1.Set(el2) if el1.Equal(el2) == 0 { t.Error("failed to set the value") } // Mutate source var el2.Add(el2, el2) if el1.Equal(el2) == 1 { t.Error("shouldn't have changed") } } func TestScalarSet(t *testing.T) { // Test this, because the internal scalar representation being hard-copyable isn't part of the spec. // 32-byte little endian value of "1" scOne := make([]byte, 32) scOne[0] = 0x01 sc1, sc2 := NewScalar(), NewScalar() // sc1 <- 1 sc1.SetCanonicalBytes(scOne) // 1 != 0 if sc1.Equal(sc2) == 1 { t.Error("shouldn't be the same") } // sc2 <- sc1 sc2.Set(sc1) // 1 == 1 if sc1.Equal(sc2) == 0 { t.Error("failed to set the value") } // sc1 <- 1 + 1 sc1.Add(sc1, sc1) // 2 != 1 if sc1.Equal(sc2) == 1 { t.Error("shouldn't have changed") } } func TestConstants(t *testing.T) { // From RFC 9496, Section 4.1. t.Run("d", func(t *testing.T) { testConstant(t, d, "37095705934669439343138083508754565189542113879843219016388785533085940283555") }) t.Run("sqrtM1", func(t *testing.T) { testConstant(t, sqrtM1, "19681161376707505956807079304988542015446066515923890162744021073123829784752") }) t.Run("sqrtADMinusOne", func(t *testing.T) { testConstant(t, sqrtADMinusOne, "25063068953384623474111414158702152701244531502492656460079210482610430750235") }) t.Run("invSqrtAMinusD", func(t *testing.T) { testConstant(t, invSqrtAMinusD, "54469307008909316920995813868745141605393597292927456921205312896311721017578") }) t.Run("oneMinusDSQ", func(t *testing.T) { testConstant(t, oneMinusDSQ, "1159843021668779879193775521855586647937357759715417654439879720876111806838") }) t.Run("dMinusOneSQ", func(t *testing.T) { testConstant(t, dMinusOneSQ, "40440834346308536858101042469323190826248399146238708352240133220865137265952") }) } func testConstant(t *testing.T, f *field.Element, decimal string) { b, ok := new(big.Int).SetString(decimal, 10) if !ok { t.Fatal("invalid decimal") } buf := b.FillBytes(make([]byte, 32)) for i := 0; i < len(buf)/2; i++ { buf[i], buf[len(buf)-i-1] = buf[len(buf)-i-1], buf[i] } if !bytes.Equal(f.Bytes(), buf) { t.Errorf("expected %x", buf) } } golang-github-gtank-ristretto255-0.2.0/scalar.go000066400000000000000000000102311514567254100214360ustar00rootroot00000000000000// Copyright 2019 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package ristretto255 import ( "encoding/base64" "errors" "filippo.io/edwards25519" ) // A Scalar is an element of the ristretto255 scalar field, as specified in // RFC 9496, Section 4.4. That is, an integer modulo // // l = 2^252 + 27742317777372353535851937790883648493 // // The zero value is a valid zero element. type Scalar struct { s edwards25519.Scalar } // NewScalar returns a Scalar set to the value 0. func NewScalar() *Scalar { return &Scalar{} } // Set sets the value of s to x and returns s. func (s *Scalar) Set(x *Scalar) *Scalar { *s = *x return s } // Add sets s = x + y mod l and returns s. func (s *Scalar) Add(x, y *Scalar) *Scalar { s.s.Add(&x.s, &y.s) return s } // Subtract sets s = x - y mod l and returns s. func (s *Scalar) Subtract(x, y *Scalar) *Scalar { s.s.Subtract(&x.s, &y.s) return s } // Negate sets s = -x mod l and returns s. func (s *Scalar) Negate(x *Scalar) *Scalar { s.s.Negate(&x.s) return s } // Multiply sets s = x * y mod l and returns s. func (s *Scalar) Multiply(x, y *Scalar) *Scalar { s.s.Multiply(&x.s, &y.s) return s } // Invert sets s = 1 / x such that s * x = 1 mod l and returns s. // // If x is 0, the result is undefined. func (s *Scalar) Invert(x *Scalar) *Scalar { s.s.Invert(&x.s) return s } // FromUniformBytes sets s to a uniformly distributed value given 64 uniformly // distributed random bytes. // // Deprecated: use SetUniformBytes. This API will be removed before v1.0.0. func (s *Scalar) FromUniformBytes(x []byte) *Scalar { if _, err := s.SetUniformBytes(x); err != nil { panic(err.Error()) } return s } // SetUniformBytes sets s to a uniformly distributed value given 64 uniformly // distributed random bytes by interpreting the 64-byte string as a 512-bit // unsigned integer in little-endian order and reducing the integer modulo l. // // If x is not of the right length, SetUniformBytes returns nil and an error, // and the receiver is unchanged. func (s *Scalar) SetUniformBytes(x []byte) (*Scalar, error) { if _, err := s.s.SetUniformBytes(x); err != nil { return nil, errors.New("ristretto255: SetUniformBytes input is not 64 bytes long") } return s, nil } // Decode sets s = x, where x is a 32 bytes little-endian encoding of s. If x is // not a canonical encoding of s, Decode returns an error and the receiver is // unchanged. // // Deprecated: use SetCanonicalBytes. This API will be removed before v1.0.0. func (s *Scalar) Decode(x []byte) error { _, err := s.SetCanonicalBytes(x) return err } // SetCanonicalBytes sets s = x, where x is a 32 bytes little-endian encoding of // s. If x is not a canonical encoding of s, SetCanonicalBytes returns nil and // an error and the receiver is unchanged. func (s *Scalar) SetCanonicalBytes(x []byte) (*Scalar, error) { if _, err := s.s.SetCanonicalBytes(x); err != nil { return nil, errors.New("ristretto255: " + err.Error()) } return s, nil } // Encode appends a 32 bytes little-endian encoding of s to b. // // Deprecated: use Bytes. This API will be removed before v1.0.0. func (s *Scalar) Encode(b []byte) []byte { ret, out := sliceForAppend(b, 32) copy(out, s.s.Bytes()) return ret } // Bytes returns the 32 bytes little-endian canonical encoding of s. func (s *Scalar) Bytes() []byte { return s.s.Bytes() } // Equal returns 1 if v and u are equal, and 0 otherwise. func (s *Scalar) Equal(u *Scalar) int { return s.s.Equal(&u.s) } // Zero sets s = 0 and returns s. func (s *Scalar) Zero() *Scalar { s.s = edwards25519.Scalar{} return s } // MarshalText implements encoding/TextMarshaler interface func (s *Scalar) MarshalText() (text []byte, err error) { b := s.Encode([]byte{}) return []byte(base64.StdEncoding.EncodeToString(b)), nil } // UnmarshalText implements encoding/TextMarshaler interface func (s *Scalar) UnmarshalText(text []byte) error { sb, err := base64.StdEncoding.DecodeString(string(text)) if err == nil { return s.Decode(sb) } return err } // String implements the Stringer interface func (s *Scalar) String() string { result, _ := s.MarshalText() return string(result) }