Update gtank/ed25519 code to fe6e0954e0

Our Ristretto-agnostic field operations are now upstreamed, so we can
drop the internal package.
This commit is contained in:
Filippo Valsorda 2019-01-21 18:13:23 -05:00
parent 7522470fbc
commit dcc5867ec2
16 changed files with 105 additions and 119 deletions

View File

@ -3,60 +3,14 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package edwards25519
package ristretto255
import (
"crypto/subtle"
"math/big"
"github.com/gtank/ristretto255/internal/edwards25519/internal/radix51"
. "github.com/gtank/ristretto255/internal/radix51"
)
// FeEqual returns 1 if a and b are equal, and 0 otherwise.
func FeEqual(a, b *FieldElement) int {
var sa, sb [32]byte
radix51.FeToBytes(&sa, a)
radix51.FeToBytes(&sb, b)
return subtle.ConstantTimeCompare(sa[:], sb[:])
}
// FeSelect sets out to v if cond == 1, and to u if cond == 0.
// out, v and u are allowed to overlap.
func FeSelect(out, v, u *FieldElement, cond int) {
b := uint64(cond) * 0xffffffffffffffff
out[0] = (b & v[0]) | (^b & u[0])
out[1] = (b & v[1]) | (^b & u[1])
out[2] = (b & v[2]) | (^b & u[2])
out[3] = (b & v[3]) | (^b & u[3])
out[4] = (b & v[4]) | (^b & u[4])
}
// FeCondNeg sets u to -u if cond == 1, and to u if cond == 0.
func FeCondNeg(u *FieldElement, cond int) {
var neg FieldElement
FeNeg(&neg, u)
b := uint64(cond) * 0xffffffffffffffff
u[0] ^= b & (u[0] ^ neg[0])
u[1] ^= b & (u[1] ^ neg[1])
u[2] ^= b & (u[2] ^ neg[2])
u[3] ^= b & (u[3] ^ neg[3])
u[4] ^= b & (u[4] ^ neg[4])
}
// FeIsNegative returns 1 if u is negative, and 0 otherwise.
func FeIsNegative(u *FieldElement) int {
var b [32]byte
radix51.FeToBytes(&b, u)
return int(b[0] & 1)
}
// FeAbs sets out to |u|. out and u are allowed to overlap.
func FeAbs(out, u *FieldElement) {
var neg FieldElement
FeNeg(&neg, u)
FeSelect(out, &neg, u, FeIsNegative(u))
}
// fePow22523 is from x/crypto/ed25519/internal/edwards25519.
func fePow22523(out, z *FieldElement) {
var t0, t1, t2 FieldElement
@ -150,7 +104,7 @@ func FeSqrtRatio(u, v *FieldElement) (int, *FieldElement) {
FeNeg(uneg, u)
correct_sign_sqrt := FeEqual(check, u)
flipped_sign_sqrt := FeEqual(check, uneg)
FeMul(uneg, uneg, &SQRT_M1)
FeMul(uneg, uneg, sqrtM1)
flipped_sign_sqrt_i := FeEqual(check, uneg)
// done with these ("freeing" a, b)
@ -159,7 +113,7 @@ func FeSqrtRatio(u, v *FieldElement) (int, *FieldElement) {
// r_prime = SQRT_M1 * r
// r = CT_SELECT(r_prime IF flipped_sign_sqrt | flipped_sign_sqrt_i ELSE r)
r_prime := &a
FeMul(r_prime, r, &SQRT_M1)
FeMul(r_prime, r, sqrtM1)
FeSelect(r, r_prime, r, flipped_sign_sqrt|flipped_sign_sqrt_i)
FeAbs(r, r)
@ -167,3 +121,13 @@ func FeSqrtRatio(u, v *FieldElement) (int, *FieldElement) {
return was_square, r
}
func fieldElementFromDecimal(s string) *FieldElement {
n, ok := new(big.Int).SetString(s, 10)
if !ok {
panic("ristretto255: not a valid decimal: " + s)
}
var fe FieldElement
FeFromBig(&fe, n)
return &fe
}

View File

@ -1,36 +0,0 @@
// 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 edwards25519
import (
"math/big"
"github.com/gtank/ristretto255/internal/edwards25519/internal/radix51"
)
var (
SQRT_M1 FieldElement
SQRT_AD_MINUS_ONE FieldElement
INVSQRT_A_MINUS_D FieldElement
ONE_MINUS_D_SQ FieldElement
D_MINUS_ONE_SQ FieldElement
)
func init() {
var (
CONST_SQRT_M1, _ = new(big.Int).SetString("19681161376707505956807079304988542015446066515923890162744021073123829784752", 10)
CONST_SQRT_AD_MINUS_ONE, _ = new(big.Int).SetString("25063068953384623474111414158702152701244531502492656460079210482610430750235", 10)
CONST_INVSQRT_A_MINUS_D, _ = new(big.Int).SetString("54469307008909316920995813868745141605393597292927456921205312896311721017578", 10)
CONST_ONE_MINUS_D_SQ, _ = new(big.Int).SetString("1159843021668779879193775521855586647937357759715417654439879720876111806838", 10)
CONST_D_MINUS_ONE_SQ, _ = new(big.Int).SetString("40440834346308536858101042469323190826248399146238708352240133220865137265952", 10)
)
radix51.FeFromBig(&SQRT_M1, CONST_SQRT_M1)
radix51.FeFromBig(&SQRT_AD_MINUS_ONE, CONST_SQRT_AD_MINUS_ONE)
radix51.FeFromBig(&INVSQRT_A_MINUS_D, CONST_INVSQRT_A_MINUS_D)
radix51.FeFromBig(&ONE_MINUS_D_SQ, CONST_ONE_MINUS_D_SQ)
radix51.FeFromBig(&D_MINUS_ONE_SQ, CONST_D_MINUS_ONE_SQ)
}

View File

@ -1,20 +0,0 @@
// 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 edwards25519
import (
"github.com/gtank/ristretto255/internal/edwards25519/internal/group"
"github.com/gtank/ristretto255/internal/edwards25519/internal/radix51"
)
// Expose some types and functions from the internal package to ristretto255.
type ExtendedGroupElement = group.ExtendedGroupElement
type FieldElement = radix51.FieldElement
var FeMul = radix51.FeMul
var FeSquare = radix51.FeSquare
var FeNeg = radix51.FeNeg

View File

@ -1,6 +1,6 @@
package group
import "github.com/gtank/ristretto255/internal/edwards25519/internal/radix51"
import "github.com/gtank/ristretto255/internal/radix51"
var (
// d, a constant in the curve equation

View File

@ -5,7 +5,7 @@ package group
import (
"math/big"
field "github.com/gtank/ristretto255/internal/edwards25519/internal/radix51"
field "github.com/gtank/ristretto255/internal/radix51"
)
// From EFD https://hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html

View File

@ -1,4 +1,5 @@
// Copyright (c) 2017 George Tankersley. All rights reserved.
// Copyright (c) 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.
@ -7,6 +8,7 @@
package radix51
import (
"crypto/subtle"
"math/big"
"math/bits"
)
@ -330,3 +332,49 @@ func FeToBig(h *FieldElement) *big.Int {
out := new(big.Int)
return out.SetBits(words)
}
// FeEqual returns 1 if a and b are equal, and 0 otherwise.
func FeEqual(a, b *FieldElement) int {
var sa, sb [32]byte
FeToBytes(&sa, a)
FeToBytes(&sb, b)
return subtle.ConstantTimeCompare(sa[:], sb[:])
}
// FeSelect sets out to v if cond == 1, and to u if cond == 0.
// out, v and u are allowed to overlap.
func FeSelect(out, v, u *FieldElement, cond int) {
b := uint64(cond) * 0xffffffffffffffff
out[0] = (b & v[0]) | (^b & u[0])
out[1] = (b & v[1]) | (^b & u[1])
out[2] = (b & v[2]) | (^b & u[2])
out[3] = (b & v[3]) | (^b & u[3])
out[4] = (b & v[4]) | (^b & u[4])
}
// FeCondNeg sets u to -u if cond == 1, and to u if cond == 0.
func FeCondNeg(u *FieldElement, cond int) {
var neg FieldElement
FeNeg(&neg, u)
b := uint64(cond) * 0xffffffffffffffff
u[0] ^= b & (u[0] ^ neg[0])
u[1] ^= b & (u[1] ^ neg[1])
u[2] ^= b & (u[2] ^ neg[2])
u[3] ^= b & (u[3] ^ neg[3])
u[4] ^= b & (u[4] ^ neg[4])
}
// FeIsNegative returns 1 if u is negative, and 0 otherwise.
func FeIsNegative(u *FieldElement) int {
var b [32]byte
FeToBytes(&b, u)
return int(b[0] & 1)
}
// FeAbs sets out to |u|. out and u are allowed to overlap.
func FeAbs(out, u *FieldElement) {
var neg FieldElement
FeNeg(&neg, u)
FeSelect(out, &neg, u, FeIsNegative(u))
}

View File

@ -148,6 +148,21 @@ func vartimeEqual(x, y FieldElement) bool {
return true
}
func TestFeEqual(t *testing.T) {
var x FieldElement = [5]uint64{1, 1, 1, 1, 1}
var y FieldElement = [5]uint64{5, 4, 3, 2, 1}
eq := FeEqual(&x, &x)
if !eq {
t.Errorf("wrong about equality")
}
eq = FeEqual(&x, &y)
if eq {
t.Errorf("wrong about inequality")
}
}
func TestFeInvert(t *testing.T) {
var x FieldElement = [5]uint64{1, 1, 1, 1, 1}
var one FieldElement = [5]uint64{1, 0, 0, 0, 0}

View File

@ -8,26 +8,40 @@
package ristretto255
import (
"github.com/gtank/ristretto255/internal/edwards25519"
"github.com/gtank/ristretto255/internal/group"
"github.com/gtank/ristretto255/internal/radix51"
)
var (
sqrtM1 = fieldElementFromDecimal(
"19681161376707505956807079304988542015446066515923890162744021073123829784752")
sqrtADMinusOne = fieldElementFromDecimal(
"25063068953384623474111414158702152701244531502492656460079210482610430750235")
invSqrtAMinusD = fieldElementFromDecimal(
"54469307008909316920995813868745141605393597292927456921205312896311721017578")
oneMinusDSQ = fieldElementFromDecimal(
"1159843021668779879193775521855586647937357759715417654439879720876111806838")
dMinusOneSQ = fieldElementFromDecimal(
"40440834346308536858101042469323190826248399146238708352240133220865137265952")
)
// Element is an element of the ristretto255 prime-order group.
type Element struct {
r edwards25519.ExtendedGroupElement
r group.ExtendedGroupElement
}
// Equal returns 1 if e is equivalent to ee, and 0 otherwise.
// Note that Elements must not be compared in any other way.
func (e *Element) Equal(ee *Element) int {
var f0, f1 edwards25519.FieldElement
var f0, f1 radix51.FieldElement
edwards25519.FeMul(&f0, &e.r.X, &ee.r.Y) // x1 * y2
edwards25519.FeMul(&f1, &e.r.Y, &ee.r.X) // y1 * x2
out := edwards25519.FeEqual(&f0, &f1)
radix51.FeMul(&f0, &e.r.X, &ee.r.Y) // x1 * y2
radix51.FeMul(&f1, &e.r.Y, &ee.r.X) // y1 * x2
out := radix51.FeEqual(&f0, &f1)
edwards25519.FeMul(&f0, &e.r.Y, &ee.r.Y) // y1 * y2
edwards25519.FeMul(&f1, &e.r.X, &ee.r.X) // x1 * x2
out = out | edwards25519.FeEqual(&f0, &f1)
radix51.FeMul(&f0, &e.r.Y, &ee.r.Y) // y1 * y2
radix51.FeMul(&f1, &e.r.X, &ee.r.X) // x1 * x2
out = out | radix51.FeEqual(&f0, &f1)
return out
}
@ -37,7 +51,8 @@ func (e *Element) Equal(ee *Element) int {
// a random element.
func (e *Element) FromUniformBytes(b []byte) {
if len(b) != 64 {
panic("ristretto255: FromUniformBytes called with a byte slice of length different than 64")
panic("ristretto255: FromUniformBytes: input is not 64 bytes long")
}
panic("ristretto255: FromUniformBytes: unimplemented")
}