From a3540ec35a1bcaed2497d8213d1b9bf86c17a32f Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Mon, 21 Jan 2019 23:39:45 -0500 Subject: [PATCH] Implement FromUniformBytes --- fe.go | 8 +++--- ristretto255.go | 72 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 5 deletions(-) diff --git a/fe.go b/fe.go index 0a8eef1..812a159 100644 --- a/fe.go +++ b/fe.go @@ -73,8 +73,8 @@ func fePow22523(out, z *FieldElement) { FeMul(out, &t0, z) } -func FeSqrtRatio(u, v *FieldElement) (int, *FieldElement) { - var a, b, c FieldElement +func feSqrtRatio(out, u, v *FieldElement) int { + var a, b FieldElement // v^3, v^7 v3, v7 := &a, &b @@ -85,7 +85,7 @@ func FeSqrtRatio(u, v *FieldElement) (int, *FieldElement) { FeMul(v7, v7, v) // v^7 = v^6 * v // r = (u * v3) * (u * v7)^((p-5)/8) - r := &c + r := out uv3, uv7 := v3, v7 // alias FeMul(uv3, u, v3) // (u * v3) FeMul(uv7, u, v7) // (u * v7) @@ -119,7 +119,7 @@ func FeSqrtRatio(u, v *FieldElement) (int, *FieldElement) { FeAbs(r, r) was_square := correct_sign_sqrt | flipped_sign_sqrt - return was_square, r + return was_square } func fieldElementFromDecimal(s string) *FieldElement { diff --git a/ristretto255.go b/ristretto255.go index c197252..eff2c87 100644 --- a/ristretto255.go +++ b/ristretto255.go @@ -54,5 +54,75 @@ func (e *Element) FromUniformBytes(b []byte) { panic("ristretto255: FromUniformBytes: input is not 64 bytes long") } - panic("ristretto255: FromUniformBytes: unimplemented") + var buf [32]byte + f := &radix51.FieldElement{} + + copy(buf[:], b[:32]) + radix51.FeFromBytes(f, &buf) + p1 := &group.ExtendedGroupElement{} + mapToPoint(p1, f) + + copy(buf[:], b[32:]) + radix51.FeFromBytes(f, &buf) + p2 := &group.ExtendedGroupElement{} + mapToPoint(p2, f) + + e.r.Add(p1, p2) +} + +func mapToPoint(out *group.ExtendedGroupElement, t *radix51.FieldElement) { + r := &radix51.FieldElement{} + radix51.FeSquare(r, t) + radix51.FeMul(r, r, sqrtM1) + + one := &radix51.FieldElement{} + radix51.FeOne(one) + minusOne := &radix51.FieldElement{} + radix51.FeNeg(minusOne, one) + + u := &radix51.FieldElement{} + radix51.FeAdd(u, r, one) + radix51.FeMul(u, u, oneMinusDSQ) + + rPlusD := &radix51.FieldElement{} + radix51.FeAdd(rPlusD, r, &group.D) + v := &radix51.FieldElement{} + radix51.FeMul(v, r, &group.D) + radix51.FeSub(v, minusOne, v) + radix51.FeMul(v, v, rPlusD) + + s := &radix51.FieldElement{} + wasSquare := feSqrtRatio(s, u, v) + sPrime := &radix51.FieldElement{} + radix51.FeMul(sPrime, s, t) + radix51.FeAbs(sPrime, sPrime) + radix51.FeNeg(sPrime, sPrime) + + c := &radix51.FieldElement{} + radix51.FeSelect(s, s, sPrime, wasSquare) + radix51.FeSelect(c, minusOne, r, wasSquare) + + N := &radix51.FieldElement{} + radix51.FeSub(N, r, one) + radix51.FeMul(N, N, c) + radix51.FeMul(N, N, dMinusOneSQ) + radix51.FeSub(N, N, v) + + sSquare := &radix51.FieldElement{} + radix51.FeSquare(sSquare, s) + + w0 := &radix51.FieldElement{} + radix51.FeMul(w0, s, v) + radix51.FeAdd(w0, w0, w0) + w1 := &radix51.FieldElement{} + radix51.FeMul(w1, N, sqrtADMinusOne) + w2 := &radix51.FieldElement{} + radix51.FeSub(w2, one, sSquare) + w3 := &radix51.FieldElement{} + radix51.FeAdd(w3, one, sSquare) + + radix51.FeMul(&out.X, w0, w3) + radix51.FeMul(&out.Y, w2, w1) + radix51.FeMul(&out.Z, w1, w3) + radix51.FeMul(&out.T, w0, w2) }