Skip to content

Commit

Permalink
fp25519 passing tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mmcloughlin committed Oct 27, 2021
1 parent f647d39 commit 81ebaa8
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 63 deletions.
28 changes: 20 additions & 8 deletions internal/examples/fp25519/fp.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,28 @@ var p, _ = new(big.Int).SetString("578960446186580977117854925043439539266349923
// Elt is an element of the field modulo 2^255-19.
type Elt struct{ n big.Int }

// Modp reduces z modulo p, ensuring it's in the range [0, p).
func Modp(z *Elt) {
z.n.Mod(&z.n, p)
func (z *Elt) SetInt(x *big.Int) *Elt {
z.n.Set(x)
return z.modp()
}

func (z *Elt) Int() *big.Int {
return new(big.Int).Set(&z.n)
}

// Mul computes z = x*y (mod p).
func Mul(z, x, y *Elt) {
// Mul computes z = x*y (mod p) and returns it.
func (z *Elt) Mul(x, y *Elt) *Elt {
z.n.Mul(&x.n, &y.n)
Modp(z)
return z.modp()
}

// Sqr computes z = x^2 (mod p).
func Sqr(z, x *Elt) { Mul(z, x, x) }
// Sqr computes z = x^2 (mod p) and returns it.
func (z *Elt) Sqr(x *Elt) *Elt {
return z.Mul(x, x)
}

// modp reduces z modulo p, ensuring it's in the range [0, p).
func (z *Elt) modp() *Elt {
z.n.Mod(&z.n, p)
return z
}
31 changes: 31 additions & 0 deletions internal/examples/fp25519/fp_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package fp25519

import (
"crypto/rand"
"math/big"
"testing"
)

func RandElt(t *testing.T) *Elt {
t.Helper()
one := new(big.Int).SetInt64(1)
max := new(big.Int).Sub(p, one)
x, err := rand.Int(rand.Reader, max)
if err != nil {
t.Fatal(err)
}
x.Add(x, one)
return new(Elt).SetInt(x)
}

func TestInv(t *testing.T) {
const trials = 1 << 12
for trial := 0; trial < trials; trial++ {
x := RandElt(t)
got := new(Elt).Inv(x)
expect := new(big.Int).ModInverse(x.Int(), p)
if got.Int().Cmp(expect) != 0 {
t.FailNow()
}
}
}
64 changes: 33 additions & 31 deletions internal/examples/fp25519/inv.go
Original file line number Diff line number Diff line change
@@ -1,85 +1,87 @@
package fp25519

func Inv(z, x *Elt) {
func (z *Elt) Inv(x *Elt) *Elt {
var (
t0 = new(Elt)
t1 = new(Elt)
t2 = new(Elt)
)

Sqr(z, x)
z.Sqr(x)

Mul(z, x, z)
z.Mul(x, z)

Sqr(t0, z)
t0.Sqr(z)
for s := 1; s < 2; s++ {
Sqr(t0, t0)
t0.Sqr(t0)
}

Mul(t0, z, t0)
t0.Mul(z, t0)

Sqr(t1, t0)
t1.Sqr(t0)
for s := 1; s < 4; s++ {
Sqr(t1, t1)
t1.Sqr(t1)
}

Mul(t0, t0, t1)
t0.Mul(t0, t1)

for s := 0; s < 2; s++ {
Sqr(t0, t0)
t0.Sqr(t0)
}

Mul(t0, z, t0)
t0.Mul(z, t0)

Sqr(t1, t0)
t1.Sqr(t0)
for s := 1; s < 10; s++ {
Sqr(t1, t1)
t1.Sqr(t1)
}

Mul(t1, t0, t1)
t1.Mul(t0, t1)

for s := 0; s < 10; s++ {
Sqr(t1, t1)
t1.Sqr(t1)
}

Mul(t1, t0, t1)
t1.Mul(t0, t1)

Sqr(t2, t1)
t2.Sqr(t1)
for s := 1; s < 30; s++ {
Sqr(t2, t2)
t2.Sqr(t2)
}

Mul(t1, t1, t2)
t1.Mul(t1, t2)

Sqr(t2, t1)
t2.Sqr(t1)
for s := 1; s < 60; s++ {
Sqr(t2, t2)
t2.Sqr(t2)
}

Mul(t1, t1, t2)
t1.Mul(t1, t2)

Sqr(t2, t1)
t2.Sqr(t1)
for s := 1; s < 120; s++ {
Sqr(t2, t2)
t2.Sqr(t2)
}

Mul(t1, t1, t2)
t1.Mul(t1, t2)

for s := 0; s < 10; s++ {
Sqr(t1, t1)
t1.Sqr(t1)
}

Mul(t0, t0, t1)
t0.Mul(t0, t1)

for s := 0; s < 2; s++ {
Sqr(t0, t0)
t0.Sqr(t0)
}

Mul(t0, x, t0)
t0.Mul(x, t0)

for s := 0; s < 3; s++ {
Sqr(t0, t0)
t0.Sqr(t0)
}

Mul(z, z, t0)
z.Mul(z, t0)

return z
}
49 changes: 25 additions & 24 deletions internal/examples/fp25519/inv.tmpl
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
package fp25519

func Inv(z, x *Elt) {
var (
{{- range .Program.Temporaries }}
{{ . }} = new(Elt)
{{- end -}}
)
func (z *Elt) Inv(x *Elt) *Elt {
var (
{{- range .Program.Temporaries }}
{{ . }} = new(Elt)
{{- end -}}
)

{{ range $i := .Program.Instructions -}}
{{- with add $i.Op }}
Mul({{ $i.Output }}, {{ .X }}, {{ .Y }})
{{ end -}}
{{ range $i := .Program.Instructions -}}
{{- with add $i.Op }}
{{ $i.Output }}.Mul({{ .X }}, {{ .Y }})
{{ end -}}

{{- with double $i.Op }}
Sqr({{ $i.Output }}, {{ .X }})
{{ end -}}
{{- with double $i.Op }}
{{ $i.Output }}.Sqr({{ .X }})
{{ end -}}

{{- with shift $i.Op -}}
{{- $first := 0 -}}
{{- if ne $i.Output.Identifier .X.Identifier }}
Sqr({{ $i.Output }}, {{ .X }})
{{- $first = 1 -}}
{{- end }}
for s := {{ $first }}; s < {{ .S }}; s++ {
Sqr({{ $i.Output }}, {{ $i.Output }})
}
{{ end -}}
{{- end -}}
{{- with shift $i.Op -}}
{{- $first := 0 -}}
{{- if ne $i.Output.Identifier .X.Identifier }}
{{ $i.Output }}.Sqr({{ .X }})
{{- $first = 1 -}}
{{- end }}
for s := {{ $first }}; s < {{ .S }}; s++ {
{{ $i.Output }}.Sqr({{ $i.Output }})
}
{{ end -}}
{{- end }}
return z
}

0 comments on commit 81ebaa8

Please sign in to comment.