gmsm/sm9/bn256/generate.go
2023-04-29 10:30:57 +08:00

102 lines
2.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//go:build ignore
// +build ignore
package main
import (
"bytes"
"go/format"
"io"
"log"
"os"
"os/exec"
)
// Running this generator requires addchain v0.4.0, which can be installed with
//
// go install github.com/mmcloughlin/addchain/cmd/addchain@v0.4.0
//
func main() {
tmplAddchainFile, err := os.CreateTemp("", "addchain-template")
if err != nil {
log.Fatal(err)
}
defer os.Remove(tmplAddchainFile.Name())
if _, err := io.WriteString(tmplAddchainFile, tmplAddchain); err != nil {
log.Fatal(err)
}
if err := tmplAddchainFile.Close(); err != nil {
log.Fatal(err)
}
log.Printf("Generating gfp_invert.go...")
f, err := os.CreateTemp("", "addchain-gfp")
if err != nil {
log.Fatal(err)
}
defer os.Remove(f.Name())
cmd := exec.Command("addchain", "search", "0xb640000002a3a6f1d603ab4ff58ec74521f2934b1a7aeedbe56f9b27e351457b")
cmd.Stderr = os.Stderr
cmd.Stdout = f
if err := cmd.Run(); err != nil {
log.Fatal(err)
}
if err := f.Close(); err != nil {
log.Fatal(err)
}
cmd = exec.Command("addchain", "gen", "-tmpl", tmplAddchainFile.Name(), f.Name())
cmd.Stderr = os.Stderr
out, err := cmd.Output()
if err != nil {
log.Fatal(err)
}
out = bytes.Replace(out, []byte("Element"), []byte("gfP"), -1)
out, err = format.Source(out)
if err != nil {
log.Fatal(err)
}
if err := os.WriteFile("gfp_invert.go", out, 0644); err != nil {
log.Fatal(err)
}
}
const tmplAddchain = `// Code generated by {{ .Meta.Name }}. DO NOT EDIT.
package bn256
// Invert sets e = 1/x, and returns e.
//
// If x == 0, Invert returns e = 0.
func (e *Element) Invert(x *Element) *Element {
// Inversion is implemented as exponentiation with exponent p 2.
// The sequence of {{ .Ops.Adds }} multiplications and {{ .Ops.Doubles }} squarings is derived from the
// following addition chain generated with {{ .Meta.Module }} {{ .Meta.ReleaseTag }}.
//
{{- range lines (format .Script) }}
// {{ . }}
{{- end }}
//
var z = new(Element).Set(e)
{{- range .Program.Temporaries }}
var {{ . }} = new(Element)
{{- end }}
{{ range $i := .Program.Instructions -}}
{{- with add $i.Op }}
{{ $i.Output }}.Mul({{ .X }}, {{ .Y }})
{{- end -}}
{{- with double $i.Op }}
{{ $i.Output }}.Square({{ .X }})
{{- end -}}
{{- with shift $i.Op -}}
{{- $first := 0 -}}
{{- if ne $i.Output.Identifier .X.Identifier }}
{{ $i.Output }}.Square({{ .X }})
{{- $first = 1 -}}
{{- end }}
for s := {{ $first }}; s < {{ .S }}; s++ {
{{ $i.Output }}.Square({{ $i.Output }})
}
{{- end -}}
{{- end }}
return e.Set(z)
}
`