mirror of https://github.com/gtank/ristretto255
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:
parent
7522470fbc
commit
dcc5867ec2
|
@ -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
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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))
|
||||
}
|
|
@ -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}
|
|
@ -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")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue